Đọc một ngày trong ký hiệu xkcd


49

Trong xkcd của mình về định dạng ngày tiêu chuẩn ISO 8601, Randall chụp theo một ký hiệu thay thế khá tò mò:

nhập mô tả hình ảnh ở đây

Các số lớn là tất cả các chữ số xuất hiện trong ngày hiện tại theo thứ tự thông thường của chúng và các số nhỏ là các chỉ số dựa trên 1 về sự xuất hiện của chữ số đó. Vì vậy, ví dụ trên đại diện 2013-02-27.

Hãy xác định một đại diện ASCII cho một ngày như vậy. Dòng đầu tiên chứa các chỉ số từ 1 đến 4. Dòng thứ hai chứa các chữ số "lớn". Dòng thứ ba chứa các chỉ số 5 đến 8. Nếu có nhiều chỉ mục trong một vị trí, chúng được liệt kê cạnh nhau từ nhỏ nhất đến lớn nhất. Nếu có nhiều nhất các mchỉ mục trong một vị trí (nghĩa là trên cùng một chữ số và trong cùng một hàng), thì mỗi cột phải có các m+1ký tự rộng và được căn trái:

2  3  1  4
0  1  2  3  7
5     67    8

Xem thêm các thách thức đồng hành cho việc chuyển đổi ngược lại.

Các thách thức

Cho một ngày theo ký hiệu xkcd, xuất ngày ISO 8601 tương ứng ( YYYY-MM-DD).

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Bạn có thể cho rằng đầu vào là bất kỳ ngày hợp lệ nào giữa các năm 00009999, bao gồm.

Sẽ không có bất kỳ khoảng trắng hàng đầu nào trong đầu vào, nhưng bạn có thể giả sử rằng các dòng được đệm bằng khoảng trắng thành hình chữ nhật, chứa nhiều nhất một cột dấu cách của khoảng trắng.

Luật tiêu chuẩn được áp dụng.

Các trường hợp thử nghiệm

2  3  1  4
0  1  2  3  7
5     67    8
2013-02-27

2  3  1     4
0  1  2  4  5
   5  67 8
2015-12-24

     1234
1    2
5678
2222-11-11

   1     3  24
0  1  2  7  8
57    6     8
1878-02-08

2   4   1   3
0   1   2   6
5       678
2061-02-22

      1 4 2 3
0 1 2 3 4 5 6 8
6 5 7         8
3564-10-28

1234
1
5678
1111-11-11

1 2 3 4
0 1 2 3
8 5 6 7
0123-12-30

11
Những người viết ngày tháng theo định dạng "mèo đen" là nguyên nhân tồn tại của tôi.
Carcigenicate

1
Tha thứ cho sự thiếu hiểu biết của tôi, nhưng chính xác định dạng kỳ lạ tương ứng với ngày như thế nào? Không thể cho cuộc sống của tôi làm việc ra mẫu.
Tom Carpenter

2
@TomCarpenter Dòng dưới cùng và trên cùng cho biết nơi các số ở dòng giữa xuất hiện trong ngày. Ví dụ 1là ở trên 2, vì vậy chữ số đầu tiên là 2. 2ở trên 0, nên chữ số thứ hai là 0. 3ở trên 1, 4ở trên 3, vì vậy chúng tôi nhận được 2013bốn chữ số đầu tiên. Bây giờ 5là bên dưới 0, vì vậy chữ số thứ năm là 0, 67cả hai bên dưới 2, vì vậy cả hai chữ số đó là 2. Và cuối cùng, 8là bên dưới 7, vì vậy chữ số cuối cùng là 8, và chúng tôi kết thúc với 2013-02-27. (Các dấu gạch ngang được ẩn trong ký hiệu xkcd vì chúng ta biết chúng xuất hiện ở vị trí nào.)
Martin Ender

Câu trả lời:


8

CJam, 35 byte

ll{1$e>}*](l+eeWf%$-8>Wf=\f=2/(o'-*

Hãy thử nó ở đây . Nó hy vọng các dòng đầu vào sẽ được đệm bằng khoảng trắng.

Giải trình

llđọc hai dòng đầu vào và {1$e>}*thực hiện "quét" trên dòng thứ hai: nó lấy tất cả các tiền tố của đầu vào và tính toán tối đa của mỗi tiền tố. Đối với dòng đầu vào "0 1 2 7 8", điều này đẩy "0001112227778". Ngăn xếp của chúng tôi bây giờ trông như thế này:

"first line" '0 '0 '0 '1 '1 '1 ...

Chúng ta cần phải nắm bắt lại các giá trị vào một danh sách bằng cách sử dụng ]; cái này cũng bắt được dòng đầu tiên của chúng tôi, vì vậy chúng tôi bật nó ra bằng cách sử dụng (, để có được

"0001112227778" "first line"

như mong đợi.

eelee+ liệt kê dòng này, sau đó thực hiện tương tự cho dòng đầu vào thứ ba và nối các kết quả, để lại một cái gì đó như thế này trên đỉnh của ngăn xếp:

[[0 '5] [1 ' ] [2 ' ] [3 ' ] [4 ' ] [5 ' ] [6 ' ] [7 ' ] [8 '6] [9 '7] [10 '8] [11 ' ] [12 ' ]
 [0 '2] [1 ' ] [2 ' ] [3 ' ] [4 '4] [5 ' ] [6 ' ] [7 ' ] [8 '1] [9 ' ] [10 ' ] [11 ' ] [12 '3]]

Bây giờ ngăn xếp của chúng tôi là ["0001112227778" X]nơi Xliệt kê danh sách ở trên.

Chúng tôi lật từng cặp trong X( Wf%), sắp xếp các cặp theo từ vựng ( $) và để lại 8 cặp cuối cùng -8>. Điều này mang lại cho chúng ta một cái gì đó như:

[['1 8] ['2 0] ['3 12] ['4 4] ['5 0] ['6 8] ['7 9] ['8 10]]

Điều này hoạt động, bởi vì sắp xếp đặt tất cả các cặp có khóa '(dấu cách) trước tất cả các chữ số theo thứ tự tăng dần.

Đây là "các vị trí x " của các ký tự 12345678trên dòng thứ nhất và thứ ba: chúng ta chỉ cần truy xuất các ký tự từ dòng thứ hai (đã sửa đổi) được căn chỉnh theo chiều dọc với chúng.

Để làm điều này, chúng tôi lấy từng vị trí ( Wf=), chỉ mục vào chuỗi chúng tôi đã thực hiện trước đó ( \f=). "20610222"Bây giờ chúng ta có trên ngăn xếp: để thêm dấu gạch ngang, đầu tiên chúng ta chia thành các đoạn có độ dài hai ( 2/), in đoạn đầu tiên không có dòng mới ( (o) và nối các đoạn còn lại bằng dấu gạch ngang ( '-*).

EDIT : mẹo quét tuyệt vời, Martin! Đã lưu bốn byte.

EDIT 2 : đã lưu thêm hai byte bằng cách thay thế eelee+bằng l+ee; công trình này, bởi vì các dòng đều có độ dài tương tự, và danh sách chỉ mục trong CJam là tự động modulo độ dài danh sách, vì vậy các chỉ số n+0, n+1, n+2... độc đáo bản đồ để 0, 1, 2...

EDIT 3 : Martin đã lưu một byte khác trong bước cuối cùng của quy trình. Đẹp!


6

Bình thường, 48 43

j\-cj\-ctuuXN.xsTZK?qJhtHdKJ+hHeHGC.z*9d4 7

Phòng thử nghiệm

Yêu cầu đệm với khoảng trắng thành một hình chữ nhật.

Tôi không nghĩ rằng đây là cách tiếp cận tốt nhất, nhưng về cơ bản, nó ghi giá trị trung bình vào chỉ mục trong một chuỗi được chỉ ra bởi giá trị trên cùng hoặc dưới cùng. Chà tôi đoán rằng tôi đã có đủ thời gian để chơi golf hầu hết những thứ rõ ràng tôi thấy. : P


4

JavaScript (ES7), 115

Chức năng ẩn danh. Sử dụng các chuỗi mẫu, có một dòng mới có ý nghĩa và được bao gồm trong số byte.

Yêu cầu: dòng đầu vào giữa không thể ngắn hơn dòng đầu tiên hoặc cuối cùng. Yêu cầu này được thỏa mãn khi đầu vào được đệm bằng khoảng trắng để tạo thành hình chữ nhật.

x=>([a,z,b]=o=x.split`
`,d=i=0,[for(c of z)o[a[i]-1]=o[b[i++]-1]=d=+c||d],o.splice(4,2,'-',o[4],o[5],'-'),o.join``)

ES6 phiên bản 117 sử dụng .map thay vì hiểu mảng

x=>([a,z,b]=o=x.split`
`,d=0,[...z].map((c,i)=>o[a[i]-1]=o[b[i]-1]=d=+c||d],o.splice(4,2,'-',o[4],o[5],'-'),o.join``)

Ít chơi gôn

x=>(
  o=[],
  [a,z,b] = x.split`\n`,
  d=i=0,
  [ for(c of z) (
      d = +c||d, // each new digit found in z goes in d (but not the spaces and not the '0' (d starts at 0 anyway)
      o[a[i]-1] = o[b[i]-1] = d, // if the index char is space, that gives index -1 that is ignored when joining later
      ++i
  )],
  o.splice(4,2,'-',o[4],o[5],'-'), // add the dashes in the right places
  o.join``
)

Kiểm tra đoạn

f=x=>(
  [a,z,b]=o=x.split`\n`,
  d=i=0,[for(c of z)o[a[i]-1]=o[b[i++]-1]=d=+c||d],
  o.splice(4,2,'-',o[4],o[5],'-'),o.join``
)


console.log=x=>O.textContent+=x+'\n';

[['2  3  1  4\n0  1  2  3  7\n5     67    8','2013-02-27']
,['2  3  1     4\n0  1  2  4  5\n   5  67 8','2015-12-24']
,['      1234\n1     2   \n5678','2222-11-11']
,['   1     3  24\n0  1  2  7  8 \n57    6     8','1878-02-08']
,['2   4   1   3\n0   1   2   6  \n5       678','2061-02-22']
,['      1 4 2 3\n0 1 2 3 4 5 6 8\n6 5 7         8','3564-10-28']
,['1234\n1   \n5678','1111-11-11']
,['1 2 3 4\n0 1 2 3\n8 5 6 7','0123-12-30']]
.forEach(t=>(k=t[1],r=f(t[0]),console.log(t[0]+'\n'+r+'\n'+(r==k?'OK\n':'Fail\n'))))
<pre id=O></pre>


Chúc mừng bạn là người đầu tiên giải quyết cả hai thử thách. :)
Martin Ender

3

Haskell, 125 106 103 byte

a#' '=a
a#b=b
f i|[a,b,c]<-('-':)<$>lines i=[o|m<-"1234-56-78",(n,o,p)<-zip3 a(scanl1(#)b)c,m==n||m==p]

Yêu cầu đệm với khoảng trắng đến một hình chữ nhật đầy đủ.

Ví dụ sử dụng: f " 1 3 24\n0 1 2 7 8 \n57 6 8 "-> "1878-02-08".

Làm thế nào nó hoạt động:

[a,b,c]<-('-':)<$>lines i          -- split input into lines, prepend a '-' to
                                   -- each, call them a, b and c
               (scanl1(#)b)        -- fill spaces of the middle line with the
                                   -- previous char, e.g.
                                   -- "-0  1  2  7  8 " -> "-00011122277788"
        zip3 a (scanl...) c        -- combine the lines element wise into triples.
                                   -- This is our lookup table for "1234-56-78" 
o|m<-"1234...",  (n,o,p)<-zip...,  m==n||m==p
                                   -- whenever m equals n or p (i.e. was originally
                                   -- in the first or last line), take the
                                   -- corresponding char o (middle line)

2

JavaScript ES6, 231

a=>{r=[];var b=[d,f,e]=a.split`
`.map(n=>n.split``);Array(Math.max(...b.map(n=>n.length))).fill().map((m,i)=>{(m=f[i])&&m!=" "&&(c=m);[d,e].map(m=>(g=m[i])&&g!=" "&&(r[g-1]=c))}),r.splice(4,0,"-"),r.splice(7,0,"-");return r.join``}

Các trường hợp thử nghiệm .


1

Perl, 154 byte

sub{$_=$_[1];@n=/\d/g;/ +/;map{map{$p[$i++].=$_}unpack"(a$+[0])*";$i=0}@_[0,2];map{map{$r[$_-1]=$n[$i]if/\d/}s plit$"='';$i++}@p;"@r"=~s/....\K(..)/-$1-/r}

Ung dung & giải thích

sub{
    $_=$_[1]; # $_[1] is 2nd argument (i.e., 2nd line)
    @n=/\d/g; # @n now contains all digits in 2nd line
    / +/;     # $+[0] now the chunk length in 2nd line
              # Equivalent to /( +)/;$l = 1 + length $1;
    map{      # Perl golfer's for-loop
        map{ 
            $p[$i++] .= $_    # @p contains positions of each digit
        } unpack "(a$+[0])*"; # Split line into same chunk width
        $i=0 # At end of loop so we don't need $i=0 before next one
    } @_[0,2];# Outer map works on 1st and 3rd lines
    map{
        map{
            # Shove $n[$i] into ($_-1)th slot in @r if $_ is a number
            $r[$_-1] = $n[$i] if /\d/
        } split $"=''; # Equivalent to split '', but sets $"='' for free
        $i++
    }@p;
    # Concatenate @r, convert 20130227 to 2013-02-27, and return
    "@r"=~s/....\K(..)/-$1-/r
};

0

JavaScript (ES6), 131 byte

s=>[...(r=[,,,,"-",,,"-"],l=s.split`
`)[1]].map((c,i)=>(c>"-"?n=c:0,y=+l[0][i],d=+l[2][i],y?r[y-1]=n:0,d?r[d+(d>6)]=n:0))&&r.join``

Giải trình

Yêu cầu đầu vào được đệm với khoảng trắng để tạo thành một hình chữ nhật.

s=>
  [...(
    r=[,,,,"-",,,"-"], // r = array of result characters, prefill with "-" symbols
    l=s.split`
`                      // l = array of lines
  )[1]].map((c,i)=>(   // for each character on the middle line
    c>"-"?n=c:0,       // n = the most recent digit encountered
    y=+l[0][i],        // y = index on the year line at the current position
    d=+l[2][i],        // d = index on the date line at the current position
    y?r[y-1]=n:0,      // if y is a number, put n at the index y of the result
    d?r[d+(d>6)]=n:0   // if d is a number, put n at the index d (accounting for "-"s)
  ))
  &&r.join``           // return the result as a string

Kiểm tra


0

Powershell, 119 byte

$r=,'-'*99
($a=$args-split'
')[1]|% t*y|%{if($_-32){$d=$_}
$a[0,2]|%{$r[$_[+$p]-48]=$d}
$p++}
-join$r[1..4+0+5+6+0+7+8]

Kịch bản kiểm tra bị lật tẩy:

$f = {

$r=,'-'*99                       # init a result as an array of '-' repeated 99 times
($a=$args-split"`n")[1]|% t*y|%{ # split argument string, store a top, middle and bottom to $a, then for each char of the middle line...
    if($_-32){$d=$_}             # store a digit to $d if the current character of the middle is not a space
    $a[0,2]|%{                   # for the top and the bottom lines...
        $r[$_[+$p]-48]=$d        # store a digit to the result array
    }                            # Note: if char in the current position is a space, then expression $_[+$p]-48 less then 0.
                                 # In this case, the expression $r[32-48]=$d changes unused element in a end of the array.
                                 # That is why the array was created by a large.
    $p++                         # next position
}
-join$r[1..4+0+5+6+0+7+8]        # return joined char with specified numbers
                                 # Note: element with index 0 has value '-'
}

@(
,(@"
2  3  1  4   
0  1  2  3  7
5     67    8
"@,"2013-02-27")

,(@"
2  3  1     4
0  1  2  4  5
    5  67 8  
"@,"2015-12-24")

,(@"
     1234
1    2   
5678     
"@,"2222-11-11")

,(@"
1     3  24
0  1  2  7  8 
57    6     8 
"@,"1878-02-08")

,(@"
2   4   1   3
0   1   2   6
5       678  
"@,"2061-02-22")

,(@"
      1 4 2 3  
0 1 2 3 4 5 6 8
6 5 7         8
"@,"3564-10-28")

,(@"
1234
1   
5678
"@,"1111-11-11")

,(@"
1 2 3 4
0 1 2 3
8 5 6 7
"@,"0123-12-30")

) | % {
    $a,$expected = $_
    $result = &$f $a
    "$(""$result"-eq"$expected"): $result"
}

Đầu ra:

True: 2013-02-27
True: 2015-12-24
True: 2222-11-11
True: 1878-02-08
True: 2061-02-22
True: 3564-10-28
True: 1111-11-11
True: 0123-12-30

0

Thạch , 38 byte

Ỵṙ-Zn⁶Ṫ€œṗƊḊZḟ⁶V€$€;2/p/Ʋ€ẎṢṪ€s2Ḣ;jɗ”-

Hãy thử trực tuyến!

Người trợ giúp chỉ ở đó để làm cho đầu vào dễ dàng hơn; đây thực sự là một chương trình đầy đủ Hãy chắc chắn để chăm sóc :

  • Các dòng đầu tiên và cuối cùng ( '''), cũng như các dòng bên cạnh chúng (trống, ở đó cho rõ ràng).
    • Định dạng đầu vào thực tế không có dòng trống thứ hai và áp chót, và chuỗi bắt đầu và kết thúc trực tiếp bên cạnh dấu ngoặc kép, không có dòng mới ở giữa, như thế này:
      '' '1 3 24
      0 1 2 7 8 
      57 6 8 '' '
      Bạn có thể để phần chân trang trong khi sử dụng định dạng này. Đây thực sự là một chuỗi nhiều dòng của Python và các trích dẫn là cần thiết cho một số đầu vào.
  • Pad đầu vào với dấu cách! Bất kỳ đầu ra chính xác nào mà không có đầu vào đệm chính xác là hoàn toàn ngẫu nhiên và không được tôi chứng thực.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.