แปลง 1 เป็นจำนวนเต็มบวกใด ๆ โดยใช้การดำเนินการ * 3 และ / 2 เท่านั้น


11

จำนวนเต็มบวกใด ๆ สามารถรับได้โดยเริ่มต้นด้วย1และการประยุกต์ใช้ลำดับของการดำเนินงานของแต่ละคนซึ่งเป็นทั้ง"คูณด้วย 3"หรือ"หารด้วย 2 ทิ้งเหลือใด ๆ"

ตัวอย่าง (เขียน f สำหรับ * 3 และ g สำหรับ / 2):

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

เขียนโปรแกรมด้วยพฤติกรรมดังต่อไปนี้:

อินพุต : จำนวนเต็มบวกใด ๆ ผ่าน stdin หรือรหัสฮาร์ดโค้ด (ถ้าฮาร์ดโค้ดตัวเลขอินพุตจะถูกแยกออกจากความยาวของโปรแกรม)
เอาต์พุต : สตริงของ f's และ g's เช่นนั้น<input> = 1 <string>(ดังในตัวอย่าง) สตริงดังกล่าวในลำดับที่กลับกันก็ยอมรับได้ หมายเหตุ: ผลลัพธ์ประกอบด้วย f's และ g เท่านั้นหรือว่างเปล่า

ผู้ชนะคือรายการที่มีจำนวนไบต์น้อยที่สุดของprogram-plus-outputเมื่อ 41 คืออินพุต


1
คุณรู้ได้อย่างไรว่านี่เป็นเรื่องจริง
marinus

@marinus นี้เชื่อว่าเป็นจริง (แต่ยังไม่ได้พิสูจน์) กำลังมองหาหลักฐานบางอย่าง
Fabinout

@marinus คุณสามารถพิสูจน์ได้ว่าเป็นไปได้โดยการสืบเชื้อสาย (หรือเทียบเท่าโดยการเหนี่ยวนำที่แข็งแกร่ง) แยกตัวพิมพ์บนx mod 3: ถ้าx=3yสร้าง y แล้วใช้f; ถ้าx=3y+1สร้าง2y+1และนำไปใช้fแล้วg; ถ้าเป็นเช่นx=3y+2นั้นมันจะซับซ้อน แต่ก็เป็นแบบเรียกซ้ำ
Peter Taylor

ในบันทึกแยกต่างหากผลลัพธ์จะต้องอยู่ในลำดับของแอปพลิเคชันหรือจะเรียงลำดับองค์ประกอบได้เช่นกัน?
Peter Taylor

@PeterTaylor ไม่ว่าจะด้วยวิธีใดก็ตาม
res

คำตอบ:


3

GolfScript คะแนน 64 (43-2 + 23)

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

(41 คือ hardcoded ดังนั้น -2 อักขระสำหรับคะแนน) ผลลัพธ์คือ

fffgffggffggffgggffgggg

อันใดคือ 23 ตัวอักษร (ไม่มีบรรทัดใหม่) โดยการสร้างรหัสรับประกันว่าจะส่งกลับ (หนึ่งใน) การเป็นตัวแทนที่สั้นที่สุด


การอ้างอิงผู้ใช้Darren Stoneในการแก้ไขที่แนะนำในโพสต์นี้: "ฉันไม่สามารถแสดงความคิดเห็นได้ที่นี่ดังนั้นฉันจะออกจากการแก้ไขผลลัพธ์นี้ไม่รวมอักขระสองตัวแรก" 1 "และไม่ได้สะท้อนอยู่ในคะแนนควรเป็น แก้ไขได้ง่ายและยังเป็นทางออกสั้น ๆ อย่างไม่น่าเชื่อไชโย! " (ฉันปฏิเสธ แต่คิดว่าฉันควรพกข้อความนี้ไปด้วย)
Doorknob

@ Doorknob ความท้าทายระบุว่า"1 "ไม่ควรรวมอยู่ในผลลัพธ์
Howard

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

แก้ไข 1 (2 * i + 1)% 3 == 0 -> (2 * i)% 3 == 1

Nota Bene ถ้าคุณใช้ Java 6 และไม่ใช่ Java 7 ในขณะเล่นกอล์ฟคุณสามารถใช้

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

โครงสร้าง 39 ตัวอักษรแทนโครงสร้างมาตรฐานซึ่งมีความยาว 53 อักขระ


(2*i+1)%3==0เทียบเท่ากับi%3==1
Howard

ใช่แล้ว. ขอบคุณ
Fabinout

if(X){A}else{if(Y){B}else{C}}if(X){A}else if(Y){B}else{C}มีความยาวมากกว่า นอกจากนี้คุณสามารถแทนที่==เงื่อนไขของคุณด้วย<เงื่อนไขที่สั้นกว่า
Peter Taylor

@PeterTaylor จริงวิธีการแก้ปัญหาของฉันยังคงน่าเกลียด ฉันไม่ทราบว่าส่วนที่สุ่มทำให้โค้ดสั้นลงหรือไม่
Fabinout

สตริง f / g ของคุณเริ่มต้นด้วย 'g' (ซึ่งควรจะเป็น '/ 2') ดังนั้นพวกเขาจะแปลง 1 ถึง 0 แทนที่จะเป็น 41 การเปลี่ยน f's เป็น g และในทางกลับกันดูเหมือนจะไม่เหมือนกัน ให้ 41.
res

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 chars of code (ขึ้นบรรทัดใหม่ 1 รายการ) - 2 สำหรับตัวเลขที่มีการกำหนดรหัสตายตัว + 36 chars of output

เอาท์พุท:

ffffffffffffffffgggggggggggggggggggg

1
ถ้าคุณทำm=f=0คุณสามารถทำวงด้านนอกwhile(n!=x)*(m!=x)และลบตัวแบ่ง นำมาไว้ที่ 95 ตัวอักษรของรหัส
Daniel Lubarov

@Daniel: คุณครับเป็นสุภาพบุรุษและเป็นนักวิชาการ ขอบคุณ! การส่งของคุณยังคงปลอดภัยอยู่ 10 ตัวอักษรก่อนหน้าฉัน :)
Darren Stone

1
นอกจากนี้คุณยังสามารถบันทึกบิตถ้าคุณแทนที่ทั้งหมดโดยn 3**f
Howard

1
สำหรับอินพุต = 1 โปรแกรมของคุณสร้างข้อผิดพลาด ("ชื่อ 'g' ไม่ได้ถูกกำหนด" เนื่องจากไม่ได้เข้าสู่ระบบ while-loop)
res

1
คุณสามารถตัดตัวละครอื่นออกมาโดยเขียนprint'f'*f+'g'*gซึ่งจะให้คะแนน 90-2 + ​​36 = 124
res

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' ขอบคุณ!
Daniel Lubarov

1
คุณสามารถวาง '1' (อีกครั้ง!) การตีความต้นฉบับของคำอธิบายผลลัพธ์ของคุณถูกต้อง เพลิดเพลินไปกับผู้นำ Python อีกครั้ง! :-)
Darren Stone

1
หากคุณรวมบรรทัดที่ 2, 3 และ 4 ของคุณเข้ากับl,n,f=len(t),1,0และลบออก'1',จากคำสั่งพิมพ์คะแนนของคุณจะเป็น 87-2 + 36 = 121.
res

ขอบคุณนะ - ฉันทิ้ง1,ไป l,n,f=len(t),1,0ให้จำนวนอักขระเท่ากันใช่ไหม (สำหรับแต่ละตัวแปรการ=และการขึ้นบรรทัดใหม่จะถูกแทนที่ด้วยสอง,s.)
แดเนียล Lubarov

หากแต่ละบรรทัดใหม่เป็นอักขระหนึ่งตัว (เช่น LF สไตล์ UNIX) ดังนั้นเวอร์ชันหนึ่งบรรทัดและสามบรรทัดจะมีความยาวเท่ากัน หากแต่ละบรรทัดขึ้นบรรทัดใหม่มีอักขระสองตัว (เช่น MS Windows สไตล์ CR + LF) ดังนั้นเวอร์ชันหนึ่งบรรทัดจะมีอักขระสองตัวที่สั้นกว่าเวอร์ชันสามบรรทัด คะแนน 121 ถือว่าเป็นบรรทัดใหม่หนึ่งอักขระ
res

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จึงน่าจะเป็นจริง เพื่อพิสูจน์ว่านี้มันจะพอเพียงเพื่อแสดงให้เห็นว่านี้เป็นรอบเดียวที่สามารถอยู่ซึ่งผมอาจหรือไม่อาจจะทำที่จุดในเวลาต่อมา

วิธีการแก้ปัญหาข้างต้นหลีกเลี่ยงวงจรทันทีแทนที่จะคาดเดา (ผิด) และหลีกเลี่ยงมันเป็นครั้งที่สองผ่าน

เอาท์พุท (28 ไบต์):

ggfgfgfgfggfggfgfgfggfgfgfff

Perl, คะแนน 100 (69 - 2 + 33)

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

ใช้วิธีการคาดเดาและตรวจสอบ สตริงถูกสร้างขึ้นโดยใช้การดำเนินการผกผัน (การแปลงค่าเป็น1แทนวิธีอื่น ๆ ) และสตริงจะกลายเป็นมิร์เรอร์ตามลำดับซึ่งได้รับอนุญาตจากข้อกำหนดคุณลักษณะปัญหา

เมื่อใดก็ตามที่พบว่าไม่ใช่ของสามจะถูกคูณด้วยสองเพิ่มหนึ่งถ้าผลลัพธ์จะเป็นทวีคูณของสาม เมื่อพบหลายในสามค่าจะถูกหารด้วยสาม ... เว้นแต่ว่าค่านี้เคยพบมาแล้วซึ่งบ่งบอกถึงวัฏจักรดังนั้นจึงเดาและตรวจสอบ

เอาท์พุท (33 ไบต์):

ggfgfgfgfggfggfgffgfgggfggfgfgfff

1

J, คะแนน 103 (82-2 + 23)

* หมายเหตุ: ผมตั้งชื่อคำกริยาของฉันfและgเพื่อไม่ให้สับสนกับสายการส่งออกและfg

ยากรหัส:

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ไม่ได้ไปกับการดำเนินงานในกลุ่มของเลขฐานสองซึ่งเป็นเปลี่ยนแปลงที่สำคัญที่สุดเท่าที่เป็นกระชับ เปลี่ยนชื่อตัวแปรและลบช่องว่างสำหรับ heck ของมัน แต่ทุกอย่างยังคงใช้งานได้เหมือนเดิม (การใช้งาน: 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

fแปลงรายการบูลีนเป็นตัวเลขโดยใช้ 0s *3และ 1s เป็น/2(และfloor) #:i.2^iสร้างอันดับ 2 อาร์เรย์มีทั้งหมดอันดับ 1 iอาร์เรย์แบบบูลของความยาว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.