อ่านจอแสดงผลย้อนยุค


22

ศิลปะถูกขโมยไปจากตัวเลขขนาดใด


ตัวเลข 7 ส่วนสามารถแสดงใน ASCII โดยใช้_|ตัวอักษร นี่คือตัวเลข0-9:

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|

งานของคุณคือการแยกวิเคราะห์ศิลปะเป็นตัวเลขปกติ

หมายเหตุเกี่ยวกับตัวเลข

  • แต่ละหลักมีความกว้างแตกต่างกัน
    • 1 มีความกว้างของ 1
    • 3และ7มีความ2กว้าง
    • 245689และ0ทั้งหมดที่3กว้าง

นอกจากนี้ระหว่างตัวเลขแต่ละหลักยังมีอักขระหนึ่งตัว นี่คือชุดถ่านแบบเต็ม:

 // <- ควรเป็นหนึ่งช่องว่าง แต่การจัดรูปแบบ SE ทำให้เกิดความสับสน
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

| _ |
  |
-------------
 _ 
| _ 
 _ |
-------------
 _ 
| _ 
| _ |
-------------
_ 
 |
 |
-------------
 _ 
| _ |
| _ |
-------------
 _ 
| _ |
 _ |
-------------
 _ 
| |
| _ |

อินพุต

อินพุตอาจเป็นได้ทั้งจากคอนโซลหรือเป็นสตริงที่ระบุให้กับฟังก์ชัน

เอาท์พุต

เอาท์พุทอาจถูกนำไปที่คอนโซลหรือถูกส่งกลับจากฟังก์ชั่น

ตัวอย่าง:

  _  _   _ 
|  |  | |_ 
|  |  | |_|
1776

 _   _     _ 
 _| | | | |_ 
|_  |_| | |_|
2016

   _       _ 
| |_| |_| |_ 
|  _|   |  _|
1945

   _   _   _   _   _   _ 
| | | | | | | | | | | | |
| |_| |_| |_| |_| |_| |_|
1000000

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|
0123456789

นี่เป็นโค้ดกอล์ฟที่สั้นที่สุดนับการชนะ!



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

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

มีชื่อทั่วไปสำหรับปัญหาประเภทนี้ในสาขาวิทยาศาสตร์คอมพิวเตอร์หรือไม่

ฉันไม่มีความคิด;)
J Atkin

คำตอบ:


4

Pyth, 33 30 ไบต์

sm@."/9Àøw"%%Csd409hTcC.z*3d

นี่คือแนวคิด: เมื่อเราโอนย้ายอินพุตและแยกเป็นตัวเลขแล้วเราสามารถเรียงลำดับแฮชของสตริงหลักแต่ละรายการและกำหนดให้กับค่าของพวกเขา

sm@."/9Àøw"%%Csd409hTcC.z*3d     Implicit: z=input
                      C.z        Transpose input.
                     c   *3d     Split that on "   ", a space between digits.
 m@."/9Àøw"%%Csd409hT            Map the following lambda d over that. d is a digit string.
             Csd                   Flatten the digit string, and convert from base 256.
            %   409                Modulo that by 409
           %       hT              and then by 11. All digits go to a distinct num mod 11.
   ."/9Àøw"                        The compressed string "03924785/61".
  @                                Index into that string.
s                                Flatten and implicitly output.

ลองมันนี่


เท่ห์โดยทั่วไปดูเหมือนว่าแนวทางของฉัน แต่สั้นกว่ามาก!
ลินน์

@Lynn ขออภัยด้วย มีวิธีหนึ่งที่สั้นที่สุดในการทำเช่นนี้ใน Pyth
lirtosiast

4

ทับทิมขนาด 184 ไบต์

a=0
l=$<.map{|x|x.bytes.map{|y|y==32?0:1}+[0]*2}
(0..l[0].count-1).map{|i|l[0][i]+2*l[1][i]+4*l[2][i]}.each{|x|
x>0?(a=x+2*a):(p Hash[[40,6,32,20,18,26,42,8,44,64].zip(0..9)][a];a=0)}

คำอธิบาย

  • ใช้อินพุตจาก stdin
  • แปลงสตริงเป็นลำดับไบนารี 1/0 สำหรับเซกเมนต์เปิด / ปิด
  • เข้ารหัสคอลัมน์ให้เป็นเลขฐานสอง 3 บิต
  • เข้ารหัสลำดับของตัวเลข 3 บิตเป็นตัวเลข 9 บิตใช้คอลัมน์ '0' เป็นสัญลักษณ์หยุด
  • ใช้ตารางการค้นหาเพื่อแปลงตัวเลข 9 บิตเป็นตัวเลข

นี่คือรหัสกอล์ฟครั้งแรกของฉัน ขอบคุณสำหรับความสนุก!


2
ยินดีต้อนรับสู่ PPCG! เป็นงานที่ดีมากสำหรับโพสต์แรกของคุณ!
J Atkin


2

Japt, 119 ไบต์

Ur"[|_]"1 z r" +
"R x1 qR² £"11
1 1
1151151
111
 15111
115 1
 1
115 1
111
1511
111
15  1
11511
111
115 1
111
11"q5 bXÃq

Try it here!

โอ้ geez อันนี้ยาวมาก ฉันไม่คิดว่าฉันเล่นกอล์ฟเสร็จแล้ว

คำอธิบาย

การจัดเตรียม

เราใช้การป้อนข้อมูลและแปลงใด ๆที่จะ|_ 1จากนั้นเราย้ายแปลงพื้นที่ที่สิ้นสุดแล้วแยกออกเป็นสองบรรทัดใหม่

การแปล

เราแมปผ่านอาร์เรย์ผลลัพธ์และค้นหาดัชนีที่มีแบบฟอร์มปรากฏในอาร์เรย์อ้างอิง นี่คือแผนภาพที่จะช่วย:

MAPITEM
  11
  1 1 --> This same form appears at index 0 in the reference array
  11                            |
                                |
                                V
                        change the mapitem to 0!

หลังจากนั้นเราจะเข้าร่วมอาร์เรย์ของตัวเลขและเอาท์พุท!

หมายเหตุ : คุณอาจสงสัยว่าทำไมเราต้องเปลี่ยนตัวละครแต่ละตัวเป็นซีรีย์ 1 นี้เป็นเพราะดูเหมือนว่าจะมีข้อผิดพลาด (หรือสิ่งที่ต้องการ) |_ซึ่งไม่ได้แจ้งให้เราเก็บของตัวละครที่เป็นอยู่ด้วย


ฉันสังเกตเห็น_ข้อผิดพลาด แต่ฉันไม่รู้ว่าเกิดจากอะไร
ETHproductions

ตกลง"\n\n"สามารถถูกแทนที่ด้วยและมี"\\||_" "%||_"ฉันคิดว่าคุณสามารถบันทึกไบต์ได้ด้วยการเข้ารหัสสตริงยาวในฐาน 4 (เปลี่ยนตัวอักษร 4 ตัวที่แตกต่าง0กัน1เป็น2, หรือ3, เติมเต็มความยาวหลายเท่าของ 4 จากนั้นก็วิ่งr"...."_n4 d}ข้ามมัน) แต่ด้วยเหตุผลบางประการ ฉันยังไม่ได้ใช้มัน
ETHproductions

2

Python2, 299 261 244 ไบต์

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
p=lambda l:['95572431508448853268'.find(`sum(ord(c)**i for i,c in enumerate("".join(n)))%108`)/2for n in s(l.split('\n'))]

ฉันชอบความท้าทายนี้ดีมาก!

คำอธิบาย

ฟังก์ชั่นsรับสามบรรทัดเป็นอินพุตมันพยายามค้นหาการแยกดิจิต (อักขระทั้งหมดเป็นช่องว่าง) เมื่อพบการแยกดังกล่าวจะเรียกใช้sกับส่วนที่เหลือของสามบรรทัดและเพิ่มค่าที่ส่งคืนโดยการเรียกไปยังสามบรรทัดที่ประกอบด้วยตัวเลข หากไม่มีการแยกก็หมายความว่ามีเพียงหนึ่งหลัก

ฟังก์ชั่นpเป็นจุดเริ่มต้นดังนั้นจึงต้องใช้สตริงที่แทนตัวเลข ตัวเลขจะถูกจัดเก็บเป็น "แฮช" ที่คำนวณด้วยsum(ord(c)**i for i,c in enumerate("".join(n)))%108เพื่อประหยัดพื้นที่ (ขอบคุณคำตอบอื่น ๆ !)

กันตัวอย่าง

digits="""
 _     _ 
| | |  _|
|_| | |_ """[1:]  # remove the '\n' at the beginning

p(digits)  # [0, 1, 2]

รุ่นอื่น ๆ

261 ไบต์ (py3):

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
def p(l):[print([91,21,84,31,58,76,88,41,80,68].index(sum(ord(c)**i%20 for i,c in enumerate("".join(n)))),end="")for n in s(l.split('\n'))]

249 ไบต์อันนี้โอนสาย (py2):

f="".join
s=lambda a,i=0:[a]if i==len(a)else[a[:i]]+s(a[i+1:])if all(c==' 'for c in a[i])else s(a,i=i+1)
h=lambda s:ord(s[0])**len(s)+h(s[1:])if s else 0
p=lambda l:["10220907112527153129".index(`h(f(map(f,n)))%34`)/2for n in s(zip(*l.split('\n')))]

2

JavaScript (ES6), 169 ไบต์

a=>[...(a=a.split`
`)[0]].map((b,c)=>(d={' ':0,'|':1,'_':2})[b]+d[a[1][c]]*2+d[a[2][c]]).join``.split(0).map(b=>[343,3,182,83,243,281,381,23,383,283].indexOf(+b)).join``

เริ่มต้นโดยแยกออกเป็นสามบรรทัดทำการแมปแต่ละคอลัมน์เป็นค่าจากนั้นสร้างข้อมูลเฉพาะตัวสำหรับแต่ละคอลัมน์จากค่าเหล่านั้น จากนั้นจะแยกตาม0(ข้อมูลประจำตัวของช่องว่างระหว่างคอลัมน์) และสุดท้ายจับคู่ข้อมูลเฉพาะตัวแต่ละรายการกับค่าตัวเลขซึ่งเชื่อมโยงและส่งออก


ดีมาก! ฉันหวังว่าหลามจะมีฟังก์ชั่นแยกรายการ ...
J Atkin

@JAtkin ฉันjoined เป็นสตริงเพื่อให้ฉันสามารถแยกมัน ฉันเชื่อว่าคุณสามารถทำได้ใน Python เช่นกัน?
Mwr247

0

Python 3, 281 254 ไบต์

แก้ไข

ฉันเพิ่งดูรหัสสำหรับคำตอบหลามอื่น ๆ และสังเกตว่ารหัสส่วนใหญ่คล้ายกัน เรื่องนี้มาถึงอย่างอิสระ

(เพิ่มบรรทัดใหม่สำหรับ "การอ่าน")

def p(i):
 n=[[]]
 for l in zip(*i.split('\n')):
  if all(i==" "for i in l):n+=[[]]
  else:n[-1]+=l
 return''.join(map(lambda l:str([''.join(l[2:])==x for x in
             "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"
                     .split(',')].index(1)),n))

Ungolfed:

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]
    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst
    return ''.join(map(digit, numbers))

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(num[2:]) == y for y in fingerprint].index(True))

แบบทดสอบ:

assert (parse("   _   _   _   _   _   _ \n| | | | | | | | | | | | |\n| |_| |_| |_| |_| |_| |_|") == '1000000')
assert (parse("   _       _ \n| |_| |_| |_ \n|  _|   |  _|") == '1945')
assert (parse(" _   _     _ \n _| | | | |_ \n|_  |_| | |_|") == '2016')
assert (parse(" _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|") == '0123456789')
assert (parse("  _  _   _ \n|  |  | |_ \n|  |  | |_|") == '1776')

มันทำงานอย่างไร

(หมายเหตุ: ฉันอธิบายโปรแกรม ungolfed ที่นี่เนื่องจากมันสามารถอ่านได้มากกว่าและมันมีรหัสเดียวกันแน่นอนยกเว้นdigitฟังก์ชั่นนั้นเรียงกันเป็นแลมบ์ดา)

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]

ฟังก์ชั่นหลักคือ parseฟังก์ชั่นหลักคือก่อนอื่นแยกอินพุตเป็นบรรทัดและสร้างnumbersอาร์เรย์

    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst

นี่คือส่วนที่ฉันชอบ (เนื่องจากใช้เวลานานกว่าจะคิดออก) ที่นี่เราzipมีเส้นเพื่อให้เราสามารถเข้าไปในแนวตั้งอินพุต เมื่อบรรทัดมีตัวอักษรเราจะเพิ่มไปยังหมายเลขสุดท้ายในnumbersอาร์เรย์ หากไม่มีตัวอักษรใด ๆ เราจะเพิ่มหมายเลขใหม่ลงในอาร์เรย์

    return ''.join(map(digit, numbers))

ง่ายจริงๆ numbersถูกแมปด้วยdigitฟังก์ชันและแปลงเป็นสตริง

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(x[2:]) == y for x, y in zip([num]*10, fingerprint)].index(True))

นี่คือ (ค่อนข้าง) ง่าย fingerprintคือการแสดงสตริงของตัวเลขที่สร้างขึ้นเหนือลบ 2 ตัวอักษรแรก (นี่เป็นลายนิ้วมือที่เล็กที่สุดที่ฉันสามารถหาได้) เราคืนค่าดัชนีของนัดแรก


0

Haskell, 270 207 ไบต์

อย่ายากเกินไปนี่เป็นโปรแกรมแรกของฉันที่มีคาเซล;) ฉันเกือบจะแน่ใจว่านี่สามารถตีกอล์ฟต่อไปได้ แต่ฉันไม่รู้ว่าฉันได้รับความรู้ด้านภาษาที่ จำกัด

import Data.Lists
b n=map c$splitOn["   "]$transpose$lines n
c n|e<-drop 2$concat n,Just r<-elemIndex True[e==f|f<-splitOn",""|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"]=(show r)!!0

Ungolfed:

module Main where
import Data.Lists

main :: IO ()
main = print $ parse " _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|"

parse :: String -> String
parse n = let lst = transpose $ lines n
              numbers = splitOn ["   "] lst --"   " lst
              number = map digit numbers
          in number

digit :: [String] -> Char
digit n | e <- drop 2 $ intercalate "" n
        , fingerprint <- ["|_ _ ||","|","|___ | ","_ ||","  _  ||"," ___  |","|___  |","  ||","|___ ||"," ___ ||"]
        , Just res <- elemIndex True [e == finger | finger <- fingerprint]
        = head $ show res

ขอบคุณมากสำหรับ @nimi สำหรับคำแนะนำ!


ข่าวร้ายครั้งแรก: ฉันเกรงว่าคุณจะต้องรวมimport Data.Listจำนวนไบต์ของคุณ ข่าวดีก) หากคุณมีData.Listsการติดตั้งคุณสามารถนำมันแทนและแทนที่aด้วยsplitOn: และ...map c$splitOn[" "]$transpose... ...f<-splitOn",""|_...ข) intercalate "" nเป็นหรือconcat n id=<<nc) แทนที่resด้วยชื่อตัวอักษรเดียว d) ยามใช้รูปแบบแทน:let ... in c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0
nimi

ฮิฮิโอ้โห! การนำเข้าหายไปในการคัดลอก / วาง;) ขอบคุณสำหรับเคล็ดลับทั้งหมด!
J Atkin

@nimi ขอโทษที่รบกวนคุณ แต่คุณรังเกียจที่=<<จะอธิบายสิ่งที่ทำ เอกสาร hoogle หรือลายเซ็นประเภทไม่เป็นประโยชน์สำหรับฉัน
J Atkin

=<<ในบริบทรายการคือconcatMapมันแมปฟังก์ชั่นที่ได้รับมากกว่ารายการและรวมผลลัพธ์เป็นรายการเดียว >>=ทำเช่นเดียวกัน แต่มีอาร์กิวเมนต์ที่พลิก id =<< n(หรือn >>= id) แมปฟังก์ชันข้อมูลประจำตัวเหนือรายการ (จากรายการ) คือไม่ทำอะไรกับรายการย่อยและเชื่อมโยงรายการเหล่านั้น concatดังนั้นจึงเป็นเช่นเดียวกับ
nimi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.