xkcd 표기법으로 날짜 읽기


49

그의 xkcd 에서 Randall 은 ISO 8601 표준 날짜 형식 에 대해 다소 호기심이 많은 대안 표기법을 사용했습니다.

여기에 이미지 설명을 입력하십시오

큰 숫자는 현재 날짜에 일반적인 순서대로 나타나는 모든 숫자이며, 작은 숫자는 해당 숫자의 발생을 나타내는 1부터 시작하는 인덱스입니다. 위의 예는를 나타냅니다 2013-02-27.

그러한 날짜에 대한 ASCII 표현을 정의합시다. 첫 번째 줄에는 인덱스 1-4가 포함됩니다. 두 번째 줄에는 "큰"숫자가 포함됩니다. 세 번째 줄에는 5에서 8까지의 색인이 있습니다. 단일 슬롯에 여러 개의 색인이있는 경우 가장 작은 것에서 가장 큰 것까지 나란히 나열됩니다. m단일 슬롯 (예 : 동일한 숫자 및 동일한 행) 에 최대 개수의 색인이있는 경우 각 열의 m+1문자는 넓고 왼쪽으로 정렬되어야합니다.

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

반대 전환에 대해서는 동반자 문제 도 참조하십시오 .

도전

xkcd-notation의 날짜가 제공되면 해당 ISO 8601 날짜 ( YYYY-MM-DD)를 출력하십시오 .

STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 리턴 값 또는 함수 (out) 매개 변수를 통해 결과를 출력하는 프로그램 또는 함수를 작성할 수 있습니다.

입력 값이 년 00009999를 포함 하여 유효한 날짜라고 가정 할 수 있습니다 .

입력에 선행 공백이 없지만 선에 공백으로 채워져 사각형에 공백이 있다고 가정 할 수 있습니다.이 공백에는 최대 하나의 공백이 있습니다.

표준 규칙이 적용됩니다.

테스트 사례

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
"검은 고양이"형식으로 날짜를 쓰는 사람들은 저의 존재의 허무입니다.
Carcigenicate

1
내 무지를 용서하지만 이상한 형식이 날짜와 정확히 어떻게 일치합니까? 내 인생에서 패턴을 해결할 수 없습니다.
Tom Carpenter

2
@TomCarpenter 아래쪽 및 위쪽 줄은 가운데 줄의 숫자가 날짜에서 나타나는 위치를 나타냅니다. 예를 들어 1위의 2숫자이므로 첫 번째 숫자는 2입니다. 20의 두 번째 숫자는 0입니다. 31, 43, 그래서 우리 2013는 처음 네 자리 숫자를 얻습니다 . 이제 5아래 인 0다섯 번째 디지트가되도록 0, 6그리고 7둘 이하이다 2, 그래서 그 자리의 양이다 2. 그리고 마지막 8은 아래 7에 있으므로 마지막 숫자는 8입니다 2013-02-27. 하이픈은 xkcd 표기법에 내포되어 있으므로 어떤 위치에 표시되는지 알 수 있습니다.
Martin Ender

답변:


8

CJam, 35 바이트

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

여기에서 시도하십시오 . 입력 라인이 공백으로 채워질 것으로 예상합니다.

설명

ll두 줄의 입력을 읽고 두 번째 줄 {1$e>}*에서 "스캔"을 수행합니다. 입력의 모든 접두사를 사용하고 각 접두사의 최대 값을 계산합니다. 입력 라인 "0 1 2 7 8"의 경우이 버튼을 누릅니다 "0001112227778". 스택은 다음과 같습니다 :

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

];를 사용하여 값을 목록으로 다시 캡처해야합니다 . 이뿐만 아니라 우리의 첫 번째 줄을 캡처, 그래서 우리는 사용하여 다시 팝 (, 얻을 수

"0001112227778" "first line"

예상대로.

eelee+ 이 줄을 열거 한 다음 세 번째 입력 줄에 대해 동일한 작업을 수행하고 결과를 연결하여 스택 맨 위에 다음과 같이 남겨 둡니다.

[[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]]

이제 우리의 스택은 ["0001112227778" X]여기서 X열거 된 목록 위입니다.

각 쌍을 뒤집고 X( Wf%) 쌍을 사전 식으로 정렬하고 (, $) 마지막 8 쌍을 남겨 둡니다 -8>. 이것은 우리에게 다음과 같은 것을 얻습니다.

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

정렬은 모든 '숫자 앞에 오름차순으로 키 (공백) 가있는 모든 쌍을 배치하기 때문에 작동합니다 .

첫 번째와 세 번째 줄에 있는 문자 의 " x 위치"입니다 12345678. 세로로 정렬 된 (수정 된) 두 번째 줄에서 문자 만 검색하면됩니다.

이를 위해 각 위치 ( Wf=)를 가져와 이전에 만든 문자열 ( )로 색인합니다 \f=. 우리가 "20610222"지금 스택에 : 대시를 추가하려면 먼저 우리가 길이 두 (세그먼트로 분할 2/), 줄 바꿈 (없이 첫 번째 세그먼트를 인쇄 (o) 및 대시 나머지 세그먼트에 가입 ( '-*).

편집 : 멋진 스캔 트릭, 마틴! 4 바이트를 저장했습니다.

편집 2 :로 대체 eelee+하여 두 바이트를 더 절약 했습니다 l+ee. 라인 모두 동일한 길이를 가지고 있고, CJam의 목록 색인이 자동적으로리스트의 길이를 모듈로, 그래서 인덱스가 있기 때문에이 작품 n+0, n+1, n+2... 잘 매핑 0, 1, 2...

편집 3 : Martin은 프로세스의 마지막 단계에서 다른 바이트를 저장했습니다. 좋은!


6

피스, 48 43

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

테스트 스위트

사각형으로 공백으로 채워야합니다.

나는 이것이 최선의 방법이라고 생각하지 않지만 기본적으로 상단 또는 하단 값이 가리키는 문자열로 색인에 중간 값을 씁니다. 글쎄, 내가 본 것 중 대부분을 골프로 칠 시간이 충분한 것 같아. :피


4

자바 스크립트 (ES7), 115

익명의 기능. 템플릿 문자열을 사용하면 중요하고 바이트 수에 포함되는 줄 바꿈이 있습니다.

요구 사항 : 중간 입력 라인은 첫 번째 또는 마지막 라인보다 짧을 수 없습니다. 이 요구 사항은 입력이 공백으로 채워져 사각형을 형성 할 때 충족됩니다.

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``)

배열 이해 대신 .map을 사용하는 ES6 버전 117

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``)

덜 골프

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``
)

테스트 스 니펫

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>


두 가지 과제를 모두 해결 한 첫 번째 사람이 된 것을 축하합니다. :)
Martin Ender

3

하스켈, 125 (106) 103 바이트

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]

전체 사각형에 공백이있는 패딩이 필요합니다.

사용 예 : f " 1 3 24\n0 1 2 7 8 \n57 6 8 "-> "1878-02-08".

작동 방식 :

[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

자바 스크립트 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``}

테스트 사례 .


1

펄, 154 바이트

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}

Ungolfed & 설명

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

자바 스크립트 (ES6), 131 바이트

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``

설명

사각형을 형성하려면 공백으로 입력을 채워야합니다.

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

테스트


0

Powershell, 119 바이트

$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]

Ungolfed 테스트 스크립트 :

$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"
}

산출:

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

젤리 , 38 바이트

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

온라인으로 사용해보십시오!

도우미는 입력을보다 쉽게하기 위해 존재합니다. 이것은 실제로 전체 프로그램입니다. 다음을주의하십시오 :

  • 첫 번째와 마지막 줄 ( ''')과 그 옆에있는 줄 (빈도를 위해 비어 있음).
    • 실제 입력 형식에는 두 번째와 두 번째 빈 줄이 없으며 문자열은 다음과 같이 줄 바꿈없이 따옴표 바로 옆에서 시작하고 끝납니다.
      '' '1 3 24
      012 7 8 
      57 6 8 '' '
      이 형식을 사용하는 동안 바닥 글을 그대로 둘 수 있습니다. 이것은 실제로 파이썬 멀티 라인 문자열이며 따옴표는 일부 입력에 필요합니다.
  • 후행 공백으로 입력을 채 웁니다! 올바르게 채워진 입력이없는 올바른 출력은 전적으로 우연이며, 나에게 보증하지 않습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.