ล็อคจักรยานรวมกัน


46

สถานการณ์

หลังจากทำงานเป็นเวลานานทั้งวันในสำนักงานและท่องดูstackexchange.comในที่สุดฉันก็เดินออกจากประตูเวลา 16:58 น. เหนื่อยกับวันนั้น เนื่องจากฉันยังเป็นเพียงผู้ฝึกงานโหมดการขนส่งปัจจุบันของฉันจึงเป็นจักรยาน ฉันตรงไปที่Peugeot Reynolds 501 ที่ไว้ใจได้ของฉันแต่ก่อนที่ฉันจะแล่นเรือไปได้ฉันต้องปลดล็อคก่อน ตัวล็อคเป็นรหัสล็อคสี่หลักมาตรฐาน (0-9) ผ่านทางกรอบและล้อหน้า ขณะที่ฉันพยายามตื่นตัวอยู่ฉันก็ดึงมือขึ้นเพื่อเข้าร่วม ล็อคจักรยานรวมกัน

ความท้าทาย

เนื่องจากนิ้วของฉันอ่อนล้าฉันต้องการเปลี่ยนการล็อคให้เป็นการผสมผสานที่ถูกต้องกับการเคลื่อนไหวที่น้อยที่สุด หนึ่งการเคลื่อนไหวถูกกำหนดให้เป็นหมุนโดยหนึ่งตำแหน่ง (36 องศา) ตัวอย่างเช่นมีการเคลื่อนไหวจากการ5737 5738อย่างไรก็ตามฉันสามารถที่จะจับได้ถึงสามวงติดต่อกันในเวลาเดียวกันและหมุนพวกเขาเป็นวงเดียวซึ่งนับเป็นการเคลื่อนไหวเพียงครั้งเดียวเท่านั้น ตัวอย่างนอกจากนี้ยังมีเพียงหนึ่งการเคลื่อนไหวจาก5737ไปหรือ6837 5626การย้ายจาก5737ไปยัง6838ไม่ใช่หนึ่งการเคลื่อนไหวเนื่องจากตัวเลข 1,2 และ 4 เคลื่อนไปในทิศทางเดียวกัน แต่เป็นอิสระจากตัวเลข 3

ดังนั้นสำหรับชุดค่าผสมที่กำหนดฉันสามารถเห็นได้บนล็อคจักรยาน (จำนวนเต็ม 4 หลักใด ๆ ) อะไรคือจำนวนการเคลื่อนไหวที่ต่ำที่สุดที่ฉันสามารถทำได้เพื่อปลดล็อคและใช่ฉันสามารถหมุนในทิศทางใดก็ได้ ด้วยวิธีนี้ฉันหมายความว่าฉันสามารถเปลี่ยนตัวเลขบางอย่างในทิศทางเดียวและตัวเลขอื่น ๆ ในทิศทางอื่น: การเคลื่อนไหวของฉันทั้งหมดไม่ได้เป็นแบบเข็มหรือตามเข็มนาฬิกาสำหรับการปลดล็อคแต่ละครั้ง

เพราะฉันขี้เกียจรหัสปลดล็อคของฉันคือ 0000

นี่คือรหัสกอล์ฟฉันไม่สามารถเขียนรหัสได้มากนักดังนั้นโปรแกรมที่สั้นที่สุดในจำนวนไบต์ชนะ

ข้อมูลมาจาก stdin และรหัสของคุณควรส่งออกชุดค่าผสมที่ฉันเห็นในแต่ละขั้นตอนหลังจากการเคลื่อนไหวแต่ละครั้งรวมถึง 0000 ที่สิ้นสุด เอาต์พุตชุดค่าผสมแต่ละชุดควรคั่นด้วยช่องว่าง / newline / comma / period / ampersand

ตัวอย่าง

Input: 1210
0100
0000

Input: 9871
9870
0980
0090
0000

Input: 5555
4445&3335&2225&1115&0005&0006&0007&0008&0009&0000

Input: 1234
0124 0013 0002 0001 0000

ฉันลองโพสต์สิ่งนี้บนhttp://bicycles.stackexchange.comแต่พวกเขาไม่ชอบ ...

คำเตือน: กอล์ฟครั้งแรกดังนั้นสิ่งใดที่ขาด / ข้อมูลที่ขาดหายไปใด ๆ แจ้งให้เราทราบ! นอกจากนี้ฉันทำตัวอย่างทั้งหมดด้วยมือดังนั้นอาจมีวิธีแก้ปัญหาที่เกี่ยวข้องกับการเคลื่อนไหวน้อยลง!

แก้ไข: สำหรับคำตอบที่มีเส้นทางการแก้ปัญหาหลายเส้นทางที่มีจำนวนการเคลื่อนไหวเท่ากัน (ในทางปฏิบัติทั้งหมด) ไม่มีคำตอบที่ต้องการ


18
ยินดีต้อนรับสู่ PPCG; ความท้าทายแรกที่ดีมาก!
Doorknob

4
นี่มันดูแข็งสำหรับฉัน! ยินดีต้อนรับสู่ PPCG!
Mego

1
ความท้าทายที่ดี ฉันสามารถถามสิ่งที่ควรจะส่งออกสำหรับกรณี: 7478 และ 3737?
noisyass2

1
@ noisyass2 ขอบคุณ; คำตอบของ flawr ให้สิ่งต่อไปนี้: 7478 8588 9698 0708 0808 0908 0008 0009 0000 และ 3737 2627 1517 0407 0307 0207 0107 0007 0008 0009 0000 เพียงแค่ดูที่ 3737 นี่ทำให้รู้สึก: ดูที่ 3 หลักแรกเท่านั้น: ถ้าฉันย้ายทั้งหมดของหลัก สามครั้งแรกในเวลาเดียวกันมันใช้เวลา 3 การเคลื่อนไหวสำหรับหลัก 1 และ 3 และจากนั้นอีก 4 การเคลื่อนไหวสำหรับหลัก 2 จึงรวมเจ็ด โดยที่ถ้าฉันเคลื่อนไหวทีละคนแต่ละคนใช้เวลา 3 การเคลื่อนไหวดังนั้น 9 การเคลื่อนไหว
Lui

1
ฉันสงสัยว่าชื่อ "Combination Lock" (หรือ "Bike Lock") อาจดึงดูดผู้ชมมากขึ้น
DavidC

คำตอบ:


10

Matlab, 412 327 ไบต์

Golfed (ขอบคุณ @AndrasDeak สำหรับการเล่นกอล์ฟs!):

s=dec2bin('iecbmgdoh'.'-97)-48;s=[s;-s];T=1e4;D=Inf(1,T);P=D;I=NaN(T,4);for i=1:T;I(i,:)=sprintf('%04d',i-1)-'0';end;G=input('');D(G+1)=0;for k=0:12;for n=find(D==k);for i=1:18;m=1+mod(I(n,:)+s(i,:),10)*10.^(3:-1:0)';if D(m)==Inf;D(m)=k+1;P(m)=n-1;end;end;end;end;n=0;X='0000';while n-G;n=P(n+1);X=[I(n+1,:)+48;X];end;disp(X)

รหัสนี้ใช้การเขียนโปรแกรมแบบไดนามิกบางอย่างสำหรับการค้นหา 'เส้นทาง' ที่สั้นที่สุดจากจำนวนที่กำหนดเพื่อ0000ใช้เฉพาะขั้นตอนที่เป็นไปได้ ความท้าทายนั้นเป็นเส้นทางที่สั้นที่สุดของ prioblem (หรือคุณอาจพิจารณาขั้นตอนเป็นกลุ่ม commutatuve) แต่ปัญหาก็เกิดขึ้นกับการใช้งานที่มีประสิทธิภาพ โครงสร้างพื้นฐานคืออาร์เรย์ 10,000 องค์ประกอบสองอันหนึ่งอันสำหรับการเก็บจำนวนขั้นตอนเพื่อไปยังดัชนีนั้นอีกอันหนึ่งเพื่อจัดเก็บตัวชี้ไปยัง 'โหนด' ก่อนหน้าในกราฟของเรา มันจะคำนวณ 'เส้นทาง' พร้อมกันกับตัวเลขที่เป็นไปได้อื่น ๆ ทั้งหมด

ตัวอย่าง:

9871
0981
0091
0001
0000

1210
0100
0000

Examples by @noisyass:

7478
8578
9678
0788
0899
0900
0000

3737
2627
1517
0407
0307
0207
0107
0007
0008
0009
0000

Own Example (longest sequence, shared with 6284)

4826
3826
2826
1826
0826
0926
0026
0015
0004
0003
0002
0001
0000    

รหัสเต็ม (รวมถึงความคิดเห็นบางส่วน):

%steps
s=[eye(4);1,1,0,0;0,1,1,0;0,0,1,1;1,1,1,0;0,1,1,1];
s=[s;-s];


D=NaN(1,10000);%D(n+1) = number of steps to get to n
P=NaN(1,10000);%P(n+1) was last one before n

I=NaN(10000,4);%integer representation as array
for i=0:9999; 
    I(i+1,:)=sprintf('%04d',i)-'0';
end

G=9871; % define the current number (for the golfed version replaced with input('');
D(G+1)=0;
B=10.^(3:-1:0); %base for each digit

for k=0:100; %upper bound on number of steps;
    L=find(D==k)-1;
    for n=L; %iterate all new steps
        for i=1:18; %search all new steps
            m=sum(mod(I(n+1,:)+s(i,:),10) .* [1000,100,10,1]);
            if isnan(D(m+1))
                D(m+1) = k+1;
                P(m+1)=n;
            end
        end
    end
end
n=0;%we start here
X=[];
while n~=G
    X=[I(n+1,:)+'0';X];
    n=P(n+1);
end
disp([I(G+1,:)+'0';X,''])

ดี! ในฐานะผู้ใช้ Matlab ส่วนใหญ่ฉันสงสัยว่ามันจะดีแค่ไหน
Lui

1
สำหรับการป้อน6444รหัสของคุณให้ 6444 7554 8664 9774 0884 0994 0004 0003 0002 0001 0000 ในขณะที่ฉันหาคำตอบเป็น 6444 6333 6223 61122 6000 7000 8000 9000 0000 คำตอบของฉันคือ 8 ขั้นตอนคุณคือ 10 ปัญหาและดูเหมือนว่าจะมีทั้งในรุ่น golfed และ ungolfed สิ่งนี้ได้รับการแก้ไขในการแก้ไขล่าสุดของคุณ
Lui

1
ฉันเพิ่งแก้ไขข้อผิดพลาดเล็ก ๆ ในรหัส ในแถวสุดท้ายที่ควรจะเป็นs [0,1,1,1]ถ้าเช่นนั้นคุณจะได้โซลูชัน 8 ขั้นตอนด้วย! ฉันขอโทษสำหรับความไม่สะดวก =)
ข้อบกพร่อง

1
@Lui มีห้องสนทนาMATLAB / ระดับแปดเสียงในหมู่สิ่งอื่น ๆ มันเป็นชนิดของฐานสำหรับ MATLAB languange MATLAB มาจากสนามกอล์ฟ
ข้อบกพร่อง

1
สำหรับ 4826 ฉันพบวิธีแก้ปัญหา 11 การเคลื่อนย้าย: 4826 3716 2606 1506 0406 0306 0206 0106 0007 0008 0009 0009 0000
noisyass2

4

แบตช์ - 288 ไบต์

แม้ว่าคุณจะบอกว่าพวกเขาจะต้องมีการติดต่อกัน (แหวน) ผมถือว่าโดยตรรกะ (ตามตัวอย่าง) ที่ฉันสามารถข้ามหนึ่งกลางจากไป12340224

ชุด / px =
ตั้งค่า =% x: ~ 0,1% และชุด b =% x: ~ 1,1% และชุด c =% x: ~ 2,1% และชุด d =% x: ~ 3,1%
: L
@echo% x% & ถ้า% a% == 0 (ถ้า% d% NEQ 0 ชุด / โฆษณา = d-1) ชุดอื่น / aa = a-1
@if% b% NEQ 0 ชุด / ab = b-1
@if% c% NEQ 0 ชุด / ac = c-1
@if% x% NEQ 0000 ตั้งค่า x =% a %% b %% c %% d% & กลับไป l

นี่คือโซลูชันแบทช์ของฉัน: 236 ไบต์


แก้ไข: โซลูชันที่แก้ไข

ชุด / px =
ตั้งค่า =% x: ~ 0,1% และชุด b =% x: ~ 1,1% และชุด c =% x: ~ 2,1% และชุด d =% x: ~ 3,1%
: L
@echo% x% & ชุด k = 1 & ถ้า% a% == 0 (ถ้า% d% NEQ 0 ชุด / โฆษณา = d-1 & ชุด k = 0) ชุดอื่น / aa = a-1 & ชุด k = 1
@if% b% NEQ 0 ถ้า% k% == 1 ชุด / ab = b-1 & ชุด k = 0
@ ถ้า% c% NEQ 0 ถ้า% k% == 0 ชุด / ac = c-1
@if% x% NEQ 0000 ตั้งค่า x =% a %% b %% c %% d% & กลับไป l

โซลูชั่นใหม่ (แก้ไขตามความคิดเห็นพื้นฐาน) หนัก 288 ไบต์


ฉันไม่ได้ดูคำตอบของคุณในเชิงลึก แต่ฉันพยายามที่จะทำตามตรรกะของคุณในย่อหน้าแรก คุณหมายถึงตัวอย่างใดเป็นพิเศษ และเป็นตัวอย่างของคุณไปจาก1234การ0224เป็นไม่เคลื่อนไหว แนวคิดก็คือด้วยการใช้เพียงสองนิ้วฉันสามารถจับได้ถึงสามวงติดต่อกันด้วยการจับเดียว
Lui

ฉันหมายความว่าถ้าคุณสามารถขยับวงแหวนได้ 3 วงติดต่อกันมันก็สมเหตุสมผลที่จะคิดว่าคุณสามารถขยับวงแหวนแรกและวงที่สามได้โดยหลีกเลี่ยงวงที่สอง หรือฉันควรเปลี่ยนรหัสของฉัน?
noize

สมมติฐานของคุณผิด คุณควรเปลี่ยนรหัสของคุณ คุณเห็นตรรกะตามที่อธิบายไว้ในความคิดเห็นด้านบนหรือไม่
Lui

รหัสได้รับการแก้ไข ฉันตรวจสอบกับชุดค่าผสมหลายประเภทและดูเหมือนว่าฉันจะใช้วิธีที่สั้นกว่าเสมอ
noize

สิ่งนี้ดูเหมือนจะนับถอยหลังเท่านั้นดังนั้นจึงใช้เวลานานเกินความจำเป็นสำหรับชุดค่าผสมที่มีตัวเลขสูง (เช่น 18 การเคลื่อนไหวสำหรับ 9999)
Faubi

2

Haskell - 310 ไบต์

import Data.Char
import Data.List
r=replicate
h=head
a x=map(:x)[map(`mod`10)$zipWith(+)(h x)((r n 0)++(r(4-j)q)++(r(j-n)0))|j<-[1..3],n<-[0..j],q<-[1,-1]]
x!y=h x==h y
x#[]=(nubBy(!)$x>>=a)#(filter(![(r 4 0)])x)
x#y=unlines.tail.reverse.map(intToDigit<$>)$h y
main=do x<-getLine;putStrLn$[[digitToInt<$>x]]#[]

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

ในฐานะที่เป็นวิธีการแก้ปัญหาสัตว์เดรัจฉานนี้ไม่มีประสิทธิภาพมากและอาจใช้เวลาหลายนาทีในการทำงาน

ฉันไม่ได้มีประสบการณ์กับ Haskell มากนักดังนั้นบางสิ่งอาจทำได้ดีกว่านี้


ดูเหมือนจะเป็นพื้นฐานที่มั่นคงสำหรับแนวทางของคุณ ฉันไม่เคยมีประสบการณ์กับ Haskell และไม่ได้รวบรวม / เรียกใช้วิธีการใด ๆ google ฉบับย่อไม่ให้ฉันทุกที่ที่ฉันสามารถลองใช้ได้เช่นกัน คุณสามารถให้ลิงค์ที่ให้ฉันลองทำหรือไม่? ขอบคุณ
Lui

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