* 3 및 / 2 연산 만 사용하여 1을 양의 정수로 변환하십시오.


11

1 부터 시작 하여 일련의 연산을 적용하여 양의 정수를 얻을 수 있습니다 . 각 연산은 "3을 곱함" 또는 "2를 나눠 나머지를 버립니다" .

(* 3의 경우 f, / 2의 경우 g) :

4 = 1 *3 *3 /2 = 1 ffg
6 = 1 ffggf = 1 fffgg
21 = 1 fffgfgfgggf

다음과 같은 동작으로 프로그램을 작성하십시오.

입력 : stdin 또는 하드 코딩을 통한 양의 정수. (하드 코딩 된 경우 입력 숫자는 프로그램 길이에서 제외됩니다.)
출력 : f와 g의 문자열 <input> = 1 <string>( 예에서와 같이). 이러한 문자열은 역순으로도 가능합니다. NB : 출력에 f와 g 만 포함되거나 비어 있습니다.

승자는 41이 입력 될 때 가장 적은 바이트의 프로그램 플러스 출력 항목입니다 .


1
이것이 사실인지 어떻게 알 수 있습니까?
marinus

@marinus 이것은 사실이지만 아직 입증되지는 않았습니다. 증거를 찾고 있습니다.
Fabinout

@marinus, 하강 (또는 강한 유도에 의해)에 의해 가능하다는 것을 증명할 수 있습니다. Case-split on x mod 3: if x=3yy를 구성한 다음 적용 f; 만약 x=3y+1구조 2y+1와 적용 fg; 그렇다면 x=3y+2복잡해 지지만 본질적으로 재귀 적입니다.
피터 테일러

별도의 메모에서 출력이 응용 프로그램 순서로되어 있어야합니까 아니면 구성 순서도 허용되어야합니까?
피터 테일러

@PeterTaylor 어느 쪽이든 괜찮습니다.
res

답변:


3

골프 스크립트, 64 점 (43-2 + 23)

0{)1.$2base:s{{3*}{2/}if}/41=!}do;s{103^}%+

(41은 하드 코드되어 있으므로 점수는 -2 자입니다). 출력은

fffgffggffggffgggffgggg

23 자 (줄 바꿈 없음)입니다. 코드를 구성함으로써 코드는 항상 가장 짧은 표현 중 하나를 반환합니다.


이 게시물 의 제안 된 편집 에서 사용자 Darren Stone 을 인용 했습니다. "나는 여기에 의견을 남길 수 없으므로 편집을 남길 것입니다.이 출력에는 처음 두 문자"1 "이 포함되지 않으며 점수에 반영되지 않습니다. "쉬운 수정과 여전히 매우 짧은 솔루션입니다. 건배!" (거부했지만 메시지를 전달해야한다고 생각했습니다)
Doorknob

@Doorknob 도전 과제 "1 "는 출력에 포함하지 않아야 함을 나타냅니다.
Howard

3

친구가 더러워지고 있습니다!

자바 210207 199 자

public class C{public static void main(String[] a){int i=41;String s="";while(i>1){if(i%3<1){s+="f";i/=3;}else if(i%3<2){s+="g";i+=i+1;}else{s+="g";i+=i+(Math.random()+0.5);}}System.out.println(s);}}

골퍼가 아닌 :

public class C {

    public static void main(String[] a) {

        int i = 41;
        String s = "";
        while (i > 1) {
            if (i % 3 == 0) {
                s += "f";
                i /= 3;
            } else {
                if (i % 3 == 1) {
                    s += "g";
                    i += i + 1;
                } else {
                    s += "g";
                    i += i + (Math.random() + 0.5);
                }
            }
        }
        System.out.println(s);
    }
}

출력 : 오래된 신들의 믿음에 따라, 내가 가진 가장 짧은 것은 30이었습니다. 출력은 오른쪽에서 읽어야합니다.

234

1 ggfgfgfgfggfggfgffgfggggfgffgfggfgfggggfgffgfggfgfggfgfggfgfgggggfffgfggfgfggfgfgggffgggggfffgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggfgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggggggggggggfgfgfggggfgfgfggfffgfgfggffgfgfggfgfggggffgfgfffff

108

1 gggffgfgfggggggfggggfgffggggfgfgfgfgfgffgggfgggggfggfffggfgfffffgggffggfgfgggffggfgfgggffggggggfgfgffgfgfff

편집 45

1 ggfgfgfgfgggfggfffgfggfgfgggggggffgffgfgfff

포인트들 : 318 199 + 30 = 229

edit1 (2 * i + 1) % 3 == 0-> (2 * i) % 3 == 1

골프 중 Java 7이 아닌 Java 6을 사용하는 경우 Nota Bene을 사용할 수 있습니다.

public class NoMain {
    static {
        //some code
        System.exit(1);
    }
}

53 자 길이의 표준 구조 대신 39 자 구조.


(2*i+1)%3==0에 해당합니다i%3==1
하워드

네 그렇습니다. 감사합니다
Fabinout

if(X){A}else{if(Y){B}else{C}}보다 깁니다 if(X){A}else if(Y){B}else{C}. 또한 ==조건을 더 짧은 <조건으로 바꿀 수 있습니다.
피터 테일러

@PeterTaylor 사실, 내 솔루션은 여전히 ​​추악합니다. 임의의 부분이 코드를 더 짧게 만들지 모르겠지만 출력 쓰레기를 확실히 만듭니다.
Fabinout

f / g 문자열은 'g'( '/ 2'를 의미하는 것으로 시작)로 시작하므로 41 대신 1에서 0으로 변환됩니다. f를 g로 바꾸고 그 반대로도 바꾸지 않는 것 같습니다 주는 41.
res

3

파이썬, 124 점 (90-2 + ​​36)

x=41;m=f=g=0
while(3**f!=x)*(m!=x):
 f+=1;m=3**f;g=0
 while m>x:m/=2;g+=1
print'f'*f+'g'*g

90 자 코드 (각 줄 바꿈 1 개)-하드 코드 된 입력 숫자 2 개 + 출력 36 자

산출:

ffffffffffffffffgggggggggggggggggggg

1
그렇게 m=f=0하면 외부 루프를 while(n!=x)*(m!=x)만들고 브레이크를 제거 할 수 있습니다 . 그것을 95 문자의 코드로 가져옵니다.
다니엘 루바 로프

@Daniel : 당신은 선생님이자 학자입니다. 감사! 귀하의 제출물은 여전히 ​​안전합니다. :)
대런 스톤

1
모든 교체하는 경우는 조금 더 저장할 수 있습니다 n3**f.
Howard

1
입력 = 1 인 경우 프로그램에서 오류가 발생합니다 (외부 while 루프에 들어 가지 않아서 "이름 'g'가 정의되지 않았습니다").
res

1
을 써서 다른 캐릭터를 잘라 내면 print'f'*f+'g'*g90-2 + ​​36 = 124의 점수를 얻게됩니다.
res

3

파이썬, 121 점 (87-2 + 36)

t=bin(41)
l,n,f=len(t),1,0
while bin(n)[:l]!=t:f+=1;n*=3
print(len(bin(n))-l)*'g'+f*'f'

@Darren, 출력 설명을 해석하는 방법을 모르겠지만 아마도 옳습니다. '1'을 추가했습니다. 감사!
Daniel Lubarov

1
출력 설명에 대한 원래 해석이 정확했습니다. 파이썬 리드를 다시 즐기십시오! :-)
대런 스톤

1
두 번째, 세 번째 및 네 번째 줄을에 결합하여 인쇄 명세서에서 l,n,f=len(t),1,0제거하면 '1',점수는 87-2 + 36 = 121이됩니다.
res

고마워 얘들 아-나는 떨어졌다 1,. l,n,f=len(t),1,0같은 수의 문자를 제공합니까? (각 변수를 들어, =개행 두으로 치환 ,S.)
다니엘 Lubarov

각 줄 바꿈이 한 문자 (예 : UNIX 스타일 LF) 인 경우 한 줄 및 세 줄 버전의 길이는 같습니다. 각 줄 바꿈이 두 문자 (예 : MS Windows 스타일 CR + LF) 인 경우 한 줄 버전은 세 줄 버전보다 두 줄 짧습니다. 121 점은 한 문자 줄 바꿈을 가정합니다.
res

1

펄, 89 점 (63-2 + 28)

$_=41;$_=${$g=$_%3||$_==21?g:f}?$_*2+$_%3%2:$_/3while$_>print$g

결론 : 아래의 원래 솔루션에 설명 된 순진한 접근 방식이주기에 도달하면 해당주기는 [21, 7, 15, 5, 10, 21, ...] 입니다. 1 ≤ n ≤ 10 6에 대한 반례가 없으므로, 이것은 사실 인 것 같습니다. 이것을 증명하기 위해, 이것이 내가가질 있는 유일한주기라는 것을 보여주는 것으로 충분합니다.

위의 해결책은 (잘못) 추측하는 대신 즉시 사이클을 피하고 두 번째로 피하는 것입니다.

출력 (28 바이트) :

ggfgfgfgfggfggfgfgfggfgfgfff

펄, 100 점 (69-2 + 33)

$_=41;1while$_>print$s{$_=$$g?$_*2+$_%3%2:$_/3}=$g=$_%3||$s{$_/3}?g:f

추측 및 확인 방법을 사용합니다. 문자열은 역 연산을 사용하여 구성되며 ( 다른 방법 대신 값을 1 로 변환 ) 문자열은 그에 따라 미러링되어 문제 사양에서 허용됩니다.

3의 배수가 아닌 경우에는 2를 곱하여 결과에 3의 배수가되면 1을 더합니다. 3의 배수가 발생하면이 값이 이전에 발생하지 않는 한 3으로 나누어 져 사이클을 나타내므로 추측 및 확인이됩니다.

출력 (33 바이트) :

ggfgfgfgfggfggfgffgfgggfggfgfgfff

1

J, 103 점 (82-2 + 23)

* 참고 : 내 동사의 이름 fg출력 문자열과 혼동하지, f하고 g.

하드 코딩 :

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
'gf'{~#:(>:^:(41&~:@f@#:)^:_)1

일반적인 기능 :

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
g=:3 :'''gf''{~#:(>:^:(y&~:@f@#:)^:_)1'

이진 숫자 블록에서 작동하는 것을 없애 버렸습니다 g. 압축하는 한 가장 중요한 변화였습니다 . 변수의 이름을 바꾸고 그 공백을 제거했지만 모든 기능은 여전히 ​​동일합니다. (사용법 : g 41)

J, 197 점 (174 + 23)

f =: 3 : 0
acc =. 1
for_a. y do. acc =. ((*&3)`(<.&-:)@.a) acc end.
)

g =: 3 : 0
f2 =: f"1 f.
l =. 0$0
i =. 1
while. 0=$(l=.(#~(y&=@:f2))#:i.2^i) do. i=.>:i end.
'fg'{~{.l
)

산출: ffffffffggggggggfgffggg

f0으로서 사용 횟수에 논리 값의리스트로 변환 *3같이 1S을 /2(및 floor). #:i.2^ilength의 모든 순위 1 부울 배열을 포함하는 순위 2 배열을 만듭니다 i.

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