演算* 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経由またはハードコードされた任意の正の整数。(ハードコーディングされている場合、入力数値はプログラムの長さから除外されます。)
出力:(<input> = 1 <string>例のように)fとgの文字列。このような逆の順序の文字列も受け入れられます。注意:出力にはfとgのみが含まれているか、空です。

勝者は、41が入力である場合にプログラムと出力のバイトが最も少ないエントリです。


1
これが真実であることをどのように知っていますか?
マリヌス

@marinusこれは真実であると信じられています(しかしまだ証明されていません)。いくつかの証拠を探しています。
-Fabinout

@marinus、降下によって(または同等に強力な誘導によって)可能であることを証明できます。大文字と小文字の分割x mod 3x=3yyを構成してから適用する場合f。もしx=3y+1構造2y+1とは、適用されf、その後g、その場合x=3y+2、複雑になりますが、本質的に再帰的です。
ピーターテイラー

別の注意として、出力はアプリケーションの順序である必要がありますか、それとも構成の順序も受け入れられますか?
ピーターテイラー

@PeterTaylorどちらの方法でも構いません。
解像度

回答:


3

GolfScript、スコア64(43-2 + 23)

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

(41はハードコードされているため、スコアは-2文字です)。出力は

fffgffggffggffgggffgggg

23文字です(改行なし)。構築により、コードは常に最短の表現(の1つ)を返すことを保証します。


この投稿の編集案でユーザーDarren Stoneを引用:「ここにコメントを残すことができないので、編集を終了します。この出力には最初の2文字「1」は含まれず、スコアに反映されません。簡単な修正でありながら、信じられないほど短いソリューションです。(拒否しましたが、メッセージを伝えるべきだと考えました)
ドアノブ

@Doorknobチャレンジでは"1 "、出力に含めるべきではないと述べています。
ハワード

3

友達が汚くなってきた!

JAVA 210 207 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 true、私の解決策はまだいです。ランダムな部分がコードを短くするかどうかはわかりませんが、それは確かに出力を無駄にします。
-Fabinout

あなたのf / g文字列は 'g'( '/ 2'を表すことになっている)で始まるため、41の代わりに1から0に変換されます。fをgに、またはその逆に変更しても、 41を与えます。
解像度

3

Python、スコア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文字のコードにします。
ダニエルルバロフ

@ダニエル:あなたは、紳士であり学者です。ありがとう!あなたの提出物はまだ私の前に10文字先に安全です。:)
ダレンストーン

1
あなたはすべてを交換する場合は、さらにビットを保存することができますnによって3**f
ハワード

1
入力= 1の場合、プログラムはエラーを生成します(外側のwhileループに入らないため、「name 'g' is not defined」)。
解像度

1
を書くことで別の文字を切り取ることができますprint'f'*f+'g'*g。これにより、スコアは90-2 + 36 = 124になります。-
解像度

3

Python、スコア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」を追加しました。ありがとう!
ダニエルルバロフ

1
「1」をドロップできます(もう一度!)出力の説明の元の解釈は正しかったです。再びPythonのリードをお楽しみください!:
ダレンストーン

1
2行目、3行目、および4行目をに結合し、printステートメントからl,n,f=len(t),1,0削除した'1',場合、スコアは87-2 + 36 = 121になります。
res

みんなありがとう-私はを落とした1,l,n,f=len(t),1,0同じ文字数を与えますよね?(各変数について、an =と改行は2つ,のsに置き換えられます。)
ダニエルルバロフ

各改行が1文字の場合(UNIXスタイルのLFなど)、1行バージョンと3行バージョンの長さは同じです。各改行が2文字の場合(MS WindowsスタイルのCR + LFなど)、1行バージョンは3行バージョンより2文字短くなります。121のスコアは、1文字の改行を想定しています。
解像度

1

Perl、スコア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の反例はないので、これは本当のようです。これを証明するために、これ存在できる唯一のサイクルであることを示すだけで十分です。これは後の時点で行う場合としない場合があります。

上記の解決策は、(間違って)推測するのではなく、サイクルをすぐに回避し、2回目のサイクルを回避します。

出力(28バイト):

ggfgfgfgfggfggfgfgfggfgfgfff

Perl、スコア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)

*注意:動詞fとに名前を付けました。g出力文字列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'

2進数のブロックの操作は廃止されました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をas *3、1を/2(and floor)として使用して、ブール値のリストを数値に変換します。#:i.2^ilengthのすべてのランク1ブール配列を含むランク2配列を作成しますi

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.