위치 산술을하자!


22

로부터 Wikipedia 기사 :

위치 산술 (Latin arithmeticæ localis)은 부가 적 (비 포지션) 이진수 시스템으로, 존 네이피어는 그의 논문 Rabdology (1617)에서 계산 기법으로 상징적으로나 체스 판과 같은 그리드에서 탐구 한 기술입니다.

뭐?

위치 숫자는 알파벳 문자를 사용하여 숫자를 쓰는 방법입니다.

이진 표기법은 아직 표준화되지 않았기 때문에 Napier는 이진수를 나타 내기 위해 위치 번호라고하는 것을 사용했습니다. 네이피어 시스템은 부호 값 표기법을 사용하여 숫자를 나타냅니다. 영어 알파벳의 연속 문자를 사용하여 연속 2의 거듭 제곱을 나타냅니다 .a = 2 ^ 0 = 1, b = 2 ^ 1 = 2, c = 2 ^ 2 = 4, d = 2 ^ 3 = 8, e = 2 ^ 4 = 16 등.

ab 밑 10에서 1 + 2 = 3

aabb 10 진법에서 1 + 1 + 2 + 2 = 6

참고 aabb로 단축 할 수있다 bc높은 하나 편지의 두 인스턴스를 교체하여.

부가

두 숫자를 연결하고 단순화하면됩니다.

acd밑 10에서 + bde= acdbde= abcdde= acebe= abcf=39

빼기

빼기의 두 부분에 똑같이 나타나는 모든 숫자를 제거하십시오. 확장 (변환 baa필요할 수 있음)

abde10 진 -- ad= be18

곱셈

조금 더 어렵다.

acd(13)에 def(56) 을 곱하고 싶다고합시다 . 먼저 acd수직으로 정렬하십시오 .

a
c
d

그런 다음 def첫 번째 다음에 추가 하십시오 a.

a def
c
d

이제 c는 a보다 알파벳에서 2 자리 늦습니다. 따라서 알파벳에서 2 자리를 더해 def만듭니다 fgh. 두 번째 행에 추가됩니다.

a def
c fgh
d

마지막으로 d는 c보다 알파벳에서 1 자리 늦습니다. 따라서 알파벳에서 1 자리를 더해 fgh만듭니다 ghi. 세 번째 행에 추가됩니다.

a def
c fgh
d ghi

그런 다음 오른쪽 합계를 가져옵니다. def+ fgh+ ghi= deffgghhi= deggghhi= deghhhi= deghii= deghj(728)

곱셈의 또 다른 예

입력:

bc * de

먼저:

b
c

그때

b ef
c 

그때

b ef
c fg

ef첫 줄에 적어 두었습니다 . 그 때문 bc에 시작 b하고, b우리가 이동해야하는, 그래서 알파벳의 두 번째 문자 de가 될 수 있도록, 1 개 문자로 ef.

그때

ef+fg

산출:

eh

분할

이는 매우 복잡해질 수 있기 때문에이 과제의 일부는 아닙니다.

당신의 실제 도전

프로그램이나 함수는 다음과 같은 문자열로 입력해야합니다.

a + b

그리고 당신은 출력해야합니다 :

ab

물론, 프로그램이나 기능은 사업자의과 (언어의 문자열이나 입력 제한까지) 임의의 길이의 숫자 지원해야합니다 +, -또는를 *. 몇 가지 예 :

입력:

ab + bd

산출:

acd

입력:

d - ab

산출:

ac

입력:

ab * cd

산출:

cf

노트:

  • 출력에서 문자의 순서는 중요하지 않지만 입력에서 숫자로 된 문자의 순서는 항상 오름차순이라고 가정 할 수 있습니다 (a 앞의 z).
  • 후행 줄 바꿈으로 입력하고 후행 줄 바꿈으로 출력 할 수 있습니다.
  • 당신은 할 수 없는 목록으로 입력을 받아 ab, *bd에 대한 ab * bd.
  • 영어 알파벳이 사용됩니다 ( abcdefghijklmnopqrstuvwxyz)
  • 출력을 단순화해야합니다 ( aa허용되지 않음, b필수)
  • 입력이 간단하게된다 ( b+ c아닌 aa+ bb또는 aa+ aaaa)
  • 당신은 전에 공간과 연산자 (요구할 수있다 +, -또는 *), 또는 당신은 아무것도 할 수없는 것으로 요구할 수있다.
  • 입력 당 하나의 연산자 만 있습니다.
  • 출력과 입력이 2 ^ 27-1 ( abcdefghijklmnopqrstuvwxyz)을 넘지 않는다고 가정 할 수 있습니다.
  • 이것은 이므로 바이트 단위의 최단 답변이 이깁니다!

2
d is 2 positions later in the alphabet than c이게 라이트 야? 해서는 안 1됩니까? That is added to the second row.같은 문장에서 그렇지 third않습니까?
Felipe Nardi Batista

1
@FelipeNardiBatista 영어 알파벳이 여기에 사용되어 편집되었습니다.
programmer5000

@ programmer5000 여전히 bc*de==efgh하지만 efgh입니다 240하지144
펠리페 나르디 바티스타

1
bc*de수 있어야eh
펠리페 나르디 바티스타

@Dada는 입력 당 하나의 연산자 만 있습니다.
programmer5000

답변:


3

젤리 , 26 25 바이트

i@€Øað’2*S;ḟ.Ḣ
ḲÇ€VBṚTịØa

젤리의 사업자 (사용 ×보다는 *_보다는 -으로 입력 문자열을) 영업 이익에 의해 허용 .

(연산자 주위에 공백이 필요합니다)

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오

방법?

i@€Øað’2*S;ḟ.Ḣ - Link 1, transform from input sub-string to value or operator: sub-string
i@€            - 1st index of, for €ach (or 0 if not found) [reversed @rguments] in:
   Øa          -      lowercase alphabet (i.e. a->1, b->2, ..., non-alpha->0)
     ð         - dyadic chain separation i.e. f(result above, substring):
      ’        - decrement (i.e a->0, b->1, ..., non-alpha->-1)
       2*      - 2 raised to that power
         S     - sum
          ;    - concatenate with the substring
           ḟ   - filter out:
            .  -     0.5 (for an operator substring the evaluated 0.5 is removed)
             Ḣ - head (i.e. the evaluation for a location, and the operator otherwise)

ḲÇ€VBṚTịØa - Main link: string                        e.g. 'ab × cd'
Ḳ          - split on spaces                               [['a','b'],['×'],['c','d']]
 Ç€        - last link (1) as a monadic function for €ach  [3,'×',12]
   V       - evaluate as Jelly code                        36
    B      - convert to binary                             [1,0,0,1,0,0]
     Ṛ     - reverse                                       [0,0,1,0,0,1]
      T    - truthy indexes                                [3,6]
       ị   - index into:
        Øa -     lowercase alphabet                        ['c','f'] (i.e. "cf", which is implicitly printed when run as a full program)

7

매스 매 티카, 168 바이트

FixedPoint[StringReplace[x_~~x_:>FromCharacterCode[c@x+1]],Table["a",ToExpression@StringReplace[#,x:LetterCharacter..:>ToString@Tr[2^((c=ToCharacterCode)@x-97)]]]<>""]&

내 초기 솔루션 (출력을 단순화해야한다는 것을 명확히하기 위해 게시물을 편집하기 전에)은 64바이트가 짧았습니다.

Table["a",ToExpression@StringReplace[#,x:LetterCharacter..:>ToString@Tr[2^(ToCharacterCode@x-97)]]]<>""

방금 해당 솔루션이 작동하도록 수정했습니다. 실제로 도전에 설명 된 방법을 사용하는 것이 더 짧을 수도 있지만 어쨌든 이것을 넣고 싶었습니다.

설명:

문자 코드 산술로 각 문자 시퀀스를 해당하는 정수로 바꾼 다음 결과 문자열을 표현식으로 변환하여 (정수로 자동 단순화) a정수와 동일한 길이 의 문자 문자열을 생성 한 다음 마지막으로 동일한 문자를 바꿉니다. 고정 소수점에 도달 할 때까지 다음 문자 코드가있는 문자


2
아, 1 문자 내장이 없습니까? 놀랍습니다!
programmer5000

7

자바 스크립트 (ES6) 136 134 133 바이트

Luke 덕분에 1 바이트 절약

s=>[...a='abcdefghijklmnopqrstuvwxyz'].filter((c,i)=>eval(s.replace(/\w+/g,s=>[...s].reduce((p,c)=>p|1<<a.search(c),0)))&1<<i).join``

테스트 사례


잘 했어요! 당신은 나를 이길 ...
programmer5000

이것은 십진수로 변환합니까? 그렇게 나타납니다.
programmer5000

1
@ programmer5000 그렇습니다. 많은 답변이있을 것 같습니다. (물론 내장 된 Mathematica는 제외. ^^)
Arnauld

댓글에 링크가없는 것 같습니다. 내장 된 것이 무엇입니까?
programmer5000

@ programmer5000 (실제로, 단어가 누락되었습니다.)
Arnauld

5

펄 5 , 95 바이트

94 바이트의 코드 + -p플래그.

s/\w/a x 2**(-97+ord$&)/ge;s/(.*)-\1|\+//;/\*/&&($_=$`x length$');1while s/(.)\1/chr 1+ord$1/e

온라인으로 사용해보십시오!

세 단계는 다음과 같습니다
.- s/\w/a x 2**(-97+ord$&)/ge;입력을 문자열 a로만 변환합니다 .
- s/(.*)-\1|+//;/*/&&($_=$`x length$')연산자를 실행합니다 (의 문자열에서 매우 간단합니다 a) : +연결, -첫 번째 부분에서 두 번째 부분만큼 많은 것을 제거하는 것을 의미하고 첫 번째 부분을 a*번째 부분에서만큼 여러 번 복제하는 것을 의미 a합니다. 부품.
- 1while s/(.)\1/chr 1+ord$1/e연속 된 동일한 문자를 알파벳의 다음 문자로 접습니다.


십진수로 변환되지 않는 유일한 대답! 좋은 작업!
programmer5000

1
@ programmer5000 2 개의 답변 중, 나는 그렇게 인상적이지 않을 것입니다!
Dada

5

05AB1E , 29 바이트

ð¡À¬U¦v0yvAyko+}}X.VbRvyiANèJ

온라인으로 사용해보십시오! 또는 테스트 스위트

설명

ð¡                             # split input on string
  À                            # rotate left
   ¬U¦                         # get the operator, store it in X and remove it from list
      v                        # for each side of the equation
       0                       # push 0 as an accumulator
        yv                     # for each letter in each side of the equation
          Ayk                  # get its index in the alphabet
             o                 # raise 2 to this power
              +                # add to the accumulator
               }}              # end loops
                 X.V           # apply the operator to the 2 numbers now on the stack
                    bR         # convert to binary and reverse
                      v        # for each binary digit
                       yi      # if it is true
                         ANè   # get the letter at that index in the alphabet
                            J  # join stack to a single string

5

C 및 x86 ATM, 340 바이트

-O0으로 컴파일

#define G getchar()
g(){int c,a=0;for(;islower(c=G);)a+=1<<(c-97);return a;}
main(){short o[]={[43]=0x4403,[45]=0x442b,[42]=0x6cf7};
mprotect((long)&&l&~4095,4096,7);
for(;;){int c,b=0,a=g();*(short*)&&l=o[G];G;g();asm("xchg %%eax,%0":"+m"(a));
l:asm("addl %1,%%eax":"=a"(c):"m"(a));
for(;a=c>>b;b++)if(a&=1)putchar(97+b);putchar(10);}}

설명

C에는가 없으므로 eval()x86 명령어 표를 대신 사용했습니다. 나는 모두 같은 길이 (또는 nops로 채워진)와 같은 타입의 src와 destination을 예상하는 명령어를 선택해야했습니다. 특히 MUL은 레지스터에만 쓸 수 있고 1 바이트 MUL opcode는 EAX에만 쓸 수 있다는 점이 귀찮았습니다. 또한 XCHG와 달리 메모리에서 빼는 레지스터 쓰기 SUB 명령이없는 것 같습니다.

편집하다

의견에서 요청되었으므로보다 전통적인 접근법은 다음과 같습니다.

#define G getchar()
#define return r
#define int i
g(){i c,a=0;for(;islower(c=G);)a+=1<<(c-97);r a;}
a(i x,i y){r x+y;}s(i x,i y){r x-y;}m(i x,i y){r x*y;}
main(){i(*o[])(i,i)={[43]=a,[45]=s,[42]=m};
for(;;){i c,b,a=g();b=G;G;g();c=o[b](a,g());
for(b=0;a=c>>b;b++)if(a&=1)putchar(97+b);putchar(10);}}

실제로는 몇 가지 이유로 301 자에서 약간 짧습니다. 1. 많은 기능이 필요하기 때문에 각 프로세서의 오버 헤드는 일부 전 처리기 규칙으로 잘릴 수 있습니다. 2. 현대 리눅스는 스택에서 실행되는 것을 막기 때문에 mprotect () 호출은이 희생 된 34 바이트를 비활성화합니다. 3. XCHG 호출은 매우 부적절하며 추가로 30 바이트가 소요됩니다. 그렇지 않다면 x86 콤보는 약 10-20 바이트 정도 이길 것입니다.

또한 g에서 islower () 호출을 개선하여 두 바이트에서 2 바이트를 잘라 냈습니다.


코드 크기 측면에서보다 고전적인 접근 방식과 비교할 수있는 방법을 알 수는 없지만 솔루션을 정말 좋아합니다. +1
Arnauld

5

GNU sed + coreutils, 329 바이트

그래, 나에게 무슨 일이 있었는지 모르겠지만 적어도 sed 스크립팅이 조금 나아 졌다는 것을 알고있다. 이 솔루션에는 e쉘 명령을 실행하는 GNU sed의 확장 이 필요합니다 .

/\+/{s/\+//
b S}
/-/{:E
/a+-a+/{s/(a*)(a*)-\2/\1/
b S}
s/.*/echo &|tr b-z- A-Y-/
e
s/([A-Z])/\L\1\1/g
b E}
/\*/{h
:M
/^\*/{x
s/[^\n]*//
s/\n//g
b S}
s/(.).*\*(.*)/echo \2|tr a-z \1-za-z/
e
H
g
s/.(.*)/\1/
h
s/\n.*//
b M}
:S
s/^.*$/echo &|grep -o .|sort|tr -d '\n'/
e
:L
s/(.)\1/\u\1/g
/^[a-z]*$/ q
s/.*/echo &|tr A-Z b-za/;e
b L

연산자 주위에 공백이 없다고 가정합니다. 내 터미널에서 :

$ sed -rf golf.sed <<< a+b
ab
$ sed -rf golf.sed <<< ab+bd
acd
$ sed -rf golf.sed <<< abc+b
ad
$ sed -rf golf.sed <<< d-ab
ca
$ sed -rf golf.sed <<< ab*cd
cf
$ sed -rf golf.sed <<< bc*de
eh
$ sed -rf golf.sed <<< acd*def
deghj

그리고 나보다 더 정신이없는 사람들을 위해 : 주석 버전!

#!/bin/sed -rf

/\+/ {
    s/\+//
    b simplify
}

/-/ {
    # expand pattern space; everything will now be 'a's
    :E
    /a+-a+/{
        # Remove doubled 'a's on either side of the dash. For example,
        # for input d-ab, space is now 'aaaa-aaa'; substitute this to 'a'
        s/(a*)(a*)-\2/\1/
        b simplify
    }
    # shift letters that aren't 'a' down and double them
    s/.*/echo &|tr b-z- A-Y-/;e
    s/([A-Z])/\L\1\1/g
    b E
}

/\*/ {
    # Hold space: line 1 is pattern, other lines are output
    h
    :M

    # if space starts with *, we've eaten entire arg0; sum and simplify
    /^\*/ {
        x
        s/[^\n]*//      # remove first line, which is our pattern
        s/\n//g         # remove newlines to add results together
        b simplify
    }

    # convert pattern into shifting command
    s/(.).*\*(.*)/echo \2|tr a-z \1-za-z/

    # execute it, append result to hold space
    e
    H

    # restore pattern, with leading char and all output lines removed
    g
    s/.(.*)/\1/
    h
    s/\n.*//

    b M
}

:simplify
# reorder all letters so all 'a's are before all 'b's are before all 'c's
# are before ... etc    
# See /programming/2373874
s/^.*$/echo &|grep -o .|sort|tr -d '\n'/
e

:L
# Replace repeated characters with themselves upper-cased, then translate
# upper-cased characters to what they should be.
s/(.)\1/\u\1/g
/^[a-z]*$/ q
s/.*/echo &|tr A-Z b-za/;e
b L

sed 코드를 +1하고 PPCG에 오신 것을 환영합니다! 순수 GNU sed (또는 다른 순수한 언어)에서 풀지 않을 때의 규칙은 예를 들어 설명에서 쉘 명령을 호출한다고 언급하더라도 "GNU sed + coreutils"와 같은 시스템 명령을 제목에 추가하는 것입니다. . 이는 특히 리더 보드 문제에서 순수한 GNU sed 답변과 차별화하기 위해 수행됩니다.
seshoumara

또한 매번 필요한 플래그 'f'를 제외하고 다른 플래그는 1 바이트로 계산되어야합니다. 따라서 당신의 점수는 329입니다. 당신은 설명에서 그것을 언급하고 싶을 수도 있습니다. 그리고 완성을 위해 TIO 와 같은 온라인 sed 인터프리터에 링크를 추가하는 것을 생각할 수 있습니다 .
seshoumara

모든 대화와 행동이 필요하지 않도록 여기 에 43 바이트가 더 짧습니다! 명령을 골라서 찾은 코드 버전 (-r을 포함하여 286 바이트). 더 짧을 수 있다고 확신합니다.
seshoumara

아, 알 겠어요! 또한 좋은 골프! 그래도 어떤 버전의 sed를 사용하고 있습니까? 당신은 TIO에서 일하지만, GNU sed 4.4에서는sed: file golf.sed line 24: ":" lacks a label
charliegreen

이름없는 레이블은 GNU sed에서 잘 알려진 버그이며 버전 4.3에서 수정되었습니다. 그러나 PPCG에서는 골프에 도움이되는 경우 버그를 기능으로 사용하여 모든 sed 변형 및 버전에 대한 프로그램을 작성할 수 있습니다. 버전 간의 차이는 언급하기에는 너무 작지만 (4.2 대 4.4) 변형 (표준 POSIX sed 대 확장 GNU sed)은 제목에 지정해야하며 시스템 프로그램이 있으면 언급해야합니다.
seshoumara

4

PHP, 168

eval을 사용하여 출력 오름차순

[$a,$o,$b]=explode(" ",$argn);function d($s){for(;$i<strlen($s);)$n+=2**(ord($s[$i++])-97);return$n;}for(eval("\$k=d($a)$o d($b);");$i<26;)echo$k&2**$i++?chr(96+$i):"";

PHP, 185 바이트

출력 오름차순

[$a,$o,$b]=explode(" ",$argn);function d($s){for(;$i<strlen($s);)$n+=2**(ord($s[$i++])-97);return$n;}for(;$i<26;)echo(bc.[mul,add,0,sub][ord($o)-42])(d($a),d($b))&2**$i++?chr(96+$i):"";

온라인 버전

넓히는

[$a,$o,$b]=explode(" ",$argn); # part the input into variables
function d($s){ # make decimal value
    for(;$i<strlen($s);)$n+=2**(ord($s[$i++])-97);
    return$n;
}
for(;$i<26;)
echo(bc.[mul,add,0,sub][ord($o)-42])(d($a),d($b))&2**$i++?chr(96+$i):""; # Bitwise Compare and Output

PHP, 201 바이트

출력 감소

[$a,$o,$b]=explode(" ",$argn);function d($s){for(;$i<strlen($s);)$n+=2**(ord($s[$i++])-97);return$n;}for($r=(bc.[mul,add,0,sub][ord($o)-42])(d($a),d($b));$r;$r-=2**$l)$t.=chr(97+$l=log($r,2)^0);echo$t;

온라인 버전

넓히는

[$a,$o,$b]=explode(" ",$argn); # part the input into variables
function d($s){ # make decimal value
    for(;$i<strlen($s);)$n+=2**(ord($s[$i++])-97);
    return$n;
}
for(
$r=(bc.[mul,add,0,sub][ord($o)-42])(d($a),d($b)) # result of the operation
;$r;
$r-=2**$l) # subtract the letter value 
$t.=chr(97+$l=log($r,2)^0); # find greatest letter
echo$t; # Output

4

파이썬 (3) , 176 (167) 바이트

i=lambda a:str(sum(1<<ord(i)-97for i in a))
def f(a):
 a,b,c=a.split();m=eval(i(a)+b+i(c));r=''
 while m:
  t=0
  while m>=2**t*2:t+=1
  r+=chr(97+t);m-=2**t
 return r

온라인으로 사용해보십시오!

  • 9 바이트 절약 : tutleman 덕분에

1
내가 잘못 해요 않는 한, 당신은 대체하여 두 바이트 면도 수 m>=2**(t+1)m>=2**t*2대체하여, 다섯 바이트 a=a.split();m=eval(i(a[0])+a[1]+i(a[2]))처럼 뭔가 b,c,d=a.split();m=eval(i(b)+c+i(d)).
Tutleman

1
아, 그리고 두 개의 바이트 2**(ord(i)-97)1<<ord(i)-97.
Tutleman

1
이 솔루션을 다른 솔루션과 비교하여 얼마나 읽기 쉬운 지 놀랐습니다.
Ole Tange

고맙습니다 :). 그러나 나는 파이썬이 사용하는 언어이기 때문에 그것도 생각합니다. 들여 쓰기는 바이트 수를 늘리지 만 읽을 수있게합니다. ;)
officialaimm

2

PHP, 130

for($d=a;$e=$argn[$i++];)$e!=' '?$d!=b?$$d+=1<<ord($e)-97:$b=$e:++$d;eval("for(;\$j++<27;)echo($a$b$c>>\$j-1)&1?chr(96+\$j):'';");

확장 버전 :

for($d=a;$e=$argn[$i++];)       // for each char in the input
  $e!=' '?                      //   if space
    $d!=b?                      //     if not the operation
      $$d+=1<<ord($e)-97:       //       add 2^(char - 'a')
      $b=$e:                    //     else save operation
    ++$d;                       //   else increase "pointer"
eval("for(;\$j++<27;)           // for each bit in the output
        echo($a$b$c>>\$j-1)&1?  //   calulate the result and check the bit
          chr(96+\$j):          //     output corrosponding char
          '';                   //     output nothing
     ");

로 실행하십시오 php -R <code>.


1

AWK, 201 바이트

BEGIN{RS="(.)"}n=index(V="abcdefghijklmnopqrstuvwxyz",RT){s+=2^--n}index("+-*",RT){a=s RT
s=0}END{RS="\n"
"(awk '$0="a s"'<<<1)"|getline v
for(j=26;j--;)if((s=v-2^j)>=0){v=s;c=substr(V,j+1,1)c}print c}

"(awk '$0="a s"'<<<1)"|getline v내가 할 수있는 가장 좋은 방법 evaluate입니다 AWK. 나는 AWK명령을 실행하고 있기 때문에 이것을 호출하기 위해 약간의 "속임수"일지도 모르지만, 적어도 명령은 AWK:)

바이트 수를 줄일 수있는 방법이 빠져 있다고 확신하지만 볼 수는 없습니다.

사용법은 상당히 표준입니다. 예를 들어 코드를 FILE넣고 수행하십시오.

awk -f FILE <<< "bc + ab"

공백이 필요하지 않으며 비 op / non [az] 문자는 자동으로 무시됩니다. 루프를 변경하여 "abcdefghijklmnopqrstuvwxyz"보다 큰 숫자로 작업하도록 확장 할 수 있습니다. 나누기하려면 단순히 /조작 문자열에 문자를 추가하십시오 :). 또한이면 빈 줄이 인쇄됩니다 result <= 0.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.