[Question]
  [
In his xkcd [about the ISO 8601 standard date format](https://xkcd.com/1179/) Randall snuck in a rather curious alternative notation:
[![enter image description here](https://i.stack.imgur.com/b1ZUO.png)](https://i.stack.imgur.com/b1ZUO.png)
The large numbers are all the digits that appear in the current date in their usual order, and the small numbers are 1-based indices of the occurrences of that digit. So the above example represents `2013-02-27`.
Let's define an ASCII representation for such a date. The first line contains the indices 1 to 4. The second line contains the "large" digits. The third line contains the indices 5 to 8. If there are multiple indices in a single slot, they are listed next to each other from smallest to largest. If there are at most `m` indices in a single slot (i.e. on the same digit, and in the same row), then each column should have be `m+1` characters wide and left-aligned:
```
2  3  1  4
0  1  2  3  7
5     67    8
```
*See also [the companion challenge](https://codegolf.stackexchange.com/q/67127/8478) for the opposite conversion.*
## The Challenge
Given a date in xkcd-notation, output the corresponding ISO 8601 date (`YYYY-MM-DD`).
You may write a program or function, taking input via STDIN (or closest alternative), command-line argument or function argument and outputting the result via STDOUT (or closest alternative), function return value or function (out) parameter.
You may assume that the input is any valid date between years `0000` and `9999`, inclusive.
There won't be any leading spaces in the input, but you may assume that the lines are padded with spaces to a rectangle, which contains at most one trailing column of spaces.
Standard [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply.
## Test Cases
```
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
```
  
[Answer]
# CJam, 35 bytes
```
ll{1$e>}*](l+eeWf%$-8>Wf=\f=2/(o'-*
```
[Try it here](http://cjam.aditsu.net/#code=ll%7B1%24e%3E%7D*%5D(l%2BeeWf%25%24-8%3EWf%3D%5Cf%3D2%2F(o'-*&input=2%20%20%204%20%20%201%20%20%203%0A0%20%20%201%20%20%202%20%20%206%0A5%20%20%20%20%20%20%20678%20%20). It expects the input lines to be padded with spaces.
## Explanation
`ll` reads two lines of input, and `{1$e>}*` performs a "scan" on the second one: it it takes all prefixes of its input and computes the maximum of each prefix. For the input line `"0 1 2 7 8"`, this pushes `"0001112227778"`. Our stack now looks like this:
```
"first line" '0 '0 '0 '1 '1 '1 ...
```
We need to re-capture the values into a list ourselves using `]`; this captures our first line as well, so we pop it back out using `(`, to get
```
"0001112227778" "first line"
```
as expected.
`eelee+` enumerates this line, then does the same for a third input line, and concatenates the results, leaving something like this on the top of the stack:
```
[[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]]
```
Now our stack is `["0001112227778" X]` where `X` is the enumerated list above.
We flip each pair in `X` (`Wf%`), sort the pairs lexicographically (`$`), and leave the last 8 pairs `-8>`. This gets us something like:
```
[['1 8] ['2 0] ['3 12] ['4 4] ['5 0] ['6 8] ['7 9] ['8 10]]
```
This works, because the sort places all the pairs with key `'` (space) before all the digits in ascending order.
These are the "*x*-positions" of the characters `12345678` on the first and third lines: we only need to retrieve the characters from our (modified) second line that are vertically aligned with them.
To do this, we take each position (`Wf=`), index into the string we made earlier (`\f=`). We have `"20610222"` on the stack now: to add the dashes, first we split into segments of length two (`2/`), print the first segment without a newline (`(o`) and join the remaining segments with dashes (`'-*`).
**EDIT**: cool scan trick, Martin! Saved four bytes.
**EDIT 2**: saved two more bytes by replacing `eelee+` with `l+ee`; this works, because the lines all have the same lengths, and list indexing in CJam is automatically modulo the list length, so the indices `n+0`, `n+1`, `n+2`... nicely map to `0`, `1`, `2`... 
**EDIT 3**: Martin saved another byte in the final step of the process. Nice!
[Answer]
# Pyth, ~~48~~ 43
```
j\-cj\-ctuuXN.xsTZK?qJhtHdKJ+hHeHGC.z*9d4 7
```
[Test Suite](https://pyth.herokuapp.com/?code=j%5C-cj%5C-ctuuXN.xsTZK%3FqJhtHdKJ%2BhHeHGC.z%2a9d4+7&input=2++3++1++4+++%0A0++1++2++3++7%0A5+++++67++++8&test_suite=1&test_suite_input=2++3++1++4+++%0A0++1++2++3++7%0A5+++++67++++8%0A2++3++1+++++4%0A0++1++2++4++5%0A+++5++67+8+++%0A+++++1234%0A1++++2+++%0A5678+++++%0A+++1+++++3++24%0A0++1++2++7++8+%0A57++++6+++++8+%0A2+++4+++1+++3%0A0+++1+++2+++6%0A5+++++++678++%0A++++++1+4+2+3++%0A0+1+2+3+4+5+6+8%0A6+5+7+++++++++8&debug=0&input_size=3)
Requires padding with spaces into a rectangle.
I don't think this is the best approach, but basically it writes the middle value to the index in a string pointed at by the top or bottom value. Well I guess I had enough time to golf most of the obvious stuff I saw. :P
[Answer]
# JavaScript (ES7), 115
Anonymous function. Using template strings, there is a newline that is signifiocant and included in byte count.
Requirement: the middle input line cannot to be shorter than the first or the last. This requirement is satisfied when the input is padded with spaces to form a rectangle.
```
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** version **117** using .map instead of array comprehension
```
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``)
```
**Less golfed**
```
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``
)
```
**Test snippet**
```
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>
```
[Answer]
## Haskell, ~~125~~ ~~106~~ 103 bytes
```
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]
```
Requires padding with spaces to a full rectangle.
Usage example: `f " 1 3 24\n0 1 2 7 8 \n57 6 8 "` -> `"1878-02-08"`.
How it works:
```
[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)
```
[Answer]
# 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``}
```
[Test cases](https://jsbin.com/numayi/edit?js,console).
[Answer]
# Perl, 154 bytes
```
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 & explained
```
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
};
```
[Answer]
# JavaScript (ES6), 131 bytes
```
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``
```
## Explanation
Requires input to be padded with spaces to form a rectangle.
```
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
```
## Test
```
var solution = 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``
```
```
<textarea id="input" rows="3" cols="30">   1     3  24
0  1  2  7  8 
57    6     8 </textarea><br />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>
```
[Answer]
# Powershell, 119 bytes
```
$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 test script:
```
$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"
}
```
Output:
```
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
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 38 bytes
```
Ỵṙ-Zn⁶Ṫ€œṗƊḊZḟ⁶V€$€;2/p/Ʋ€ẎṢṪ€s2Ḣ;jɗ”-
```
[Try it online!](https://tio.run/##y0rNyan8///h7i0Pd87Ujcp71Ljt4c5Vj5rWHJ38cOf0Y10Pd3RFPdwxHygcBhRUAWJrI/0C/WObgKyHu/oe7lwEUV5s9HDHIuusk9MfNczV/V/yqHH74fb//9XV1bm4FBQUDBVAwFhBwciEywDMNVJQMFdQsFDgMjUHSZmBFQC5XEAtAA "Jelly – Try It Online")
The helper is only there to make input easier; this is actually a full program. **Be sure to care for**:
* The first and last lines (`'''`), as well as the lines next to them (empty, there for clarity).
	+ The actual input format doesn't have the second and penultimate empty lines, and the string starts and ends directly next to the quotes, without a newline in-between, like this:
	```
	'''   1     3  24
	0  1  2  7  8 
	57    6     8 '''
	```
	You can leave the footer in while using this format. This is really a Python multi-line string, and the quotes are necessary for some inputs.
* Pad the input with trailing spaces! Any correct output without correctly padded input is entirely coincidental, and isn't endorsed by me.
]