日付をxkcd表記に変換します


26

ISO 8601標準日付形式についての彼のxkcd で、ランドールはかなり奇妙な代替表記法を隠しています

ここに画像の説明を入力してください

大きな数字はすべて通常の順序で現在の日付に表示される数字であり、小さな数字はその数字の出現の1から始まるインデックスです。したがって、上記の例はを表し2013-02-27ます。

そのような日付のASCII表現を定義しましょう。最初の行にはインデックス1〜4が含まれます。2行目には「大きい」数字が含まれます。3行目には、インデックス5〜8が含まれます。1つのスロットに複数のインデックスがある場合、最小から最大の順に並んで表示されます。m単一のスロット(つまり、同じ桁、同じ行)に多くてもインデックスがある場合、各列はm+1文字幅で左揃えにする必要があります。

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

逆の変換については、コンパニオンチャレンジもご覧ください。

チャレンジ

ISO 8601日付(YYYY-MM-DD)を指定すると、対応するxkcd日付表記を出力します。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

から0000までの任意の年9999が有効な入力です。

末尾のスペースは許可されますが、先頭のスペースは許可されません。オプションで、単一の末尾の改行を出力できます。

標準の規則が適用されます。

テストケース

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

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

2222-11-11
     1234
1    2
5678

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

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

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

1111-11-11
1234
1
5678

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

回答:


1

Pyth、86 78バイト

JS{K-z\-=GheS.nmmlkd=N,mf<T5d=ZmmhkxdcK1Jmf>T4dZjbmjkmj"".[|k\ \ Gd[hNm]dcJ1eN

脳が回復したらすぐにこれをダウンさせようとします。私はそれが機能するのを見るだけで幸せでした。


5

JavaScript(ES6)、168 173

匿名関数として。テンプレート文字列を使用すると、バイトカウントに含まれる重要な改行が末尾近くにあります。

d=>d.replace(/\d/g,c=>m=(l=((o[c]=o[c]||[b,c,b])[p/2&~1]+=++p).length)>m?l:m,t=[m=p=b='',b,b],o=[])&o.map(x=>x&&x.map((x,i)=>t[i]+=(x+'     ').slice(0,m+1)))||t.join`
`

少ないゴルフ

f=d=>(
  // get the indices in o and the columns width in m
  m=0,
  p=0,
  o=[],
  d.replace(/\d/g,c=>(
    o[c] = o[c]||['',c,''], // for each found digit :array with top indices, digit, bottom indices
    o[c][p/2 & ~1] += ++p, // (p/2 and not 1) maps 0..3 to 0, 4..7 to 2
    l = o[c].length,
    m = l>m ? l : m // max indices string length in m 
  )),
  // build the output in t
  t=['','',''],
  o.map(x=> x && x.map(
    (x,i) => t[i]+=(x+'     ').slice(0,m+1)) // left justify, max value of m is 4
  ),
  t.join`\n` // return output as a newline separated string
)   

テストスニペット

f=d=>
  d.replace(/\d/g,c=>m=(l=((o[c]=o[c]||[b,c,b])[p/2&~1]+=++p).length)>m?l:m,t=[m=p=b='',b,b],o=[])&
  o.map(x=>x&&x.map((x,i)=>t[i]+=(x+'     ').slice(0,m+1)))
  ||t.join`\n`


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

;['2013-02-27','2015-12-24','2222-11-11','1878-02-08','2061-02-22','3564-10-28','1111-11-11']
.forEach(t=>console.log(t+'\n'+f(t)+'\n'))
<pre id=O></pre>


ああ、良い追加のテストケース。それを両方の課題に追加します。
マーティンエンダー

4

ルビー、200 195 189 178 162 157文字

(156文字のコード+ 1文字のコマンドラインオプション)

o={}
i=0
$_.gsub(/\d/){o[$&]||=['','']
o[$&][i/4]+="#{i+=1}"}
o=o.sort.map &:flatten
puts [1,0,2].map{|i|o.map{|c|c[i].ljust o.flatten.map(&:size).max}*' '}

サンプル実行:

bash-4.3$ ruby -n xkcd-date.rb <<< '2013-02-27'
2  3  1  4    
0  1  2  3  7 
5     67    8 

bash-4.3$ ruby -n xkcd-date.rb <<< '2222-11-11'
     1234
1    2   
5678     

bash-4.3$ ruby -n xkcd-date.rb <<< '3564-10-28'
      1 4 2 3  
0 1 2 3 4 5 6 8
6 5 7         8

2

パイソン2.7、308の 310バイト

i=raw_input().replace("-","")
s,w=sorted(set(i)),len
x,m={},0
for c in s:
    q,v=i,[""]*2
    while c in q:a=str(-~q.index(c)+(w(i)-w(q)));v[int(a)>4]+=a;q=q[q.index(c)+1:]
    m,x[c]=max(m,max(map(w,v))),v
for l in[0,1]:print"".join((lambda x:x+(-~m-w(x))*" ")("".join(x[n][l]))for n in s)+"\n"+(" "*m).join(s)*(-l+1)

うわー、それを修正するだけで2バイトかかりました!

日付を区切る必要はありません。日付は任意の長さにすることができ、日付にする必要はありません。文字列にすることもできます(ただし、ダッシュは削除されます)。真ん中の部分は、私にとってはかなりゴルファーに見えます。


1

C#、456

ゴルフ:

string  x(string p){string s=p.Replace("-", ""),a="",d="",e="";var u=new Dictionary<char,List<int>>();for(int i=0;i<s.Length;i++)if(u.ContainsKey(s[i]))u[s[i]].Add(i+1);else u.Add(s[i],new List<int>{i+1});foreach (var c in u.Keys.OrderBy(k=>k)){var t=String.Join("",u[c].Where(i=>i<5));var b=String.Join("",u[c].Where(i=>i>4));var l=Math.Max(t.Length,b.Length);var m=c+"".PadRight(l);a+=t.PadRight(l)+" ";e+=m;d+=b.PadRight(l)+" ";}return a+"\n"+e+"\n"+d;}

ゴルフをしていない:

string  x(string p)
    {
        string s = p.Replace("-", ""),a = "", d = "", e = "";;
        var u = new Dictionary<char, List<int>>();
        for (int i = 0; i < s.Length; i++) if (u.ContainsKey(s[i])) u[s[i]].Add(i + 1); else u.Add(s[i], new List<int>{ i + 1 });            
        foreach (var c in u.Keys.OrderBy(k => k))
        {
            var t = String.Join("", u[c].Where(i => i < 5));
            var b = String.Join("", u[c].Where(i => i > 4));
            var l = Math.Max(t.Length, b.Length);
            var m = c + "".PadRight(l);
            a += t.PadRight(l) + " ";
            e += m;
            d += b.PadRight(l) + " ";
        }
        return a + "\n" + e + "\n" + d;            
    }

1

Perl6、265バイト

ゴルフ

my$i=get;$i~~s:g/\-//;my@b=$i.comb.unique.sort;my$f={$i.comb[$_[1]-1]eq$_[0]??$_[1]!!''};my$g={[~] .map: $f};my$h={(@b X @^a).rotor(4).map: $g}my@a=$h(1..4);my@c=$h(5..8);my$s=max(|@a».chars,|@c».chars)+1;my$x='%-'~$s~'s';for @a,@b,@c {say [~] @_.map: *.fmt($x)}

アンゴルフド(少し)

my $i = get;
$i ~~ s:g/\-//;
my @b = $i.comb.unique.sort;
my $f = { $i.comb[$_[1]-1] eq $_[0] ?? $_[1] !! '' };
my $g = { [~] .map: $f };
my $h = { (@b X @^a).rotor(4).map: $g }
my @a = $h(1..4);
my @c = $h(5..8);
my $s = max(|@a».chars, |@c».chars)+1;
my $x = '%-'~$s~'s';
for @a,@b,@c { say [~] @_.map: *.fmt($x) }

1

Python 3、306バイト

上下の行を組み立てる前に、特定の列の最大幅を決定する方法を調査しています。それが得られたら、これらのすべてのjoin機能を使用する代わりに、行にスペースを直接組み込むことができるはずです。

j=''.join
def t(d):
 c,*l={},;i,*n=0,
 for e in d.replace('-',''):
  i+=1
  try:c[e]+=[i]
  except:c[e]=i,
 m=sorted(c)
 for x in m:
  l+=[j(str(p)for p in c[x]if p<5)]
  n+=[j(str(p)for p in c[x]if p>4)]
 f='<'+str(max(map(len,l+n)))
 return'\n'.join(map(lambda o:' '.join(format(i,f)for i in o),(l,m,n)))

1
''.join変数に保存できませんでしたか?
デニス

@デニス:ええ。なぜ私はそれを考えなかったのだろうか。たぶん私は無意識のうちにを扱っていた''.join(...)のでjoin('',...)、代わりに関数として「保存」する必要があります。
ティムペデリック

1
+=[i]できると思います+=i,
ジョナサンフレッチ

1
return '\n'-> return'\n'
ジョナサンフレッチ

1
@TimPederickよろしいです?(コンマに注意してください!)
ジョナサンフレッチ

0

PowerShellの、174の 170 168 167バイト

$a=@{}
$args|% t*y|?{$_-45}|%{if(!$a.$_){$a.$_="","","$_"}$a.$_[++$i-gt4]+=$i}
0,2,1|%{$r=$_
-join($a.Keys|sort|%{$a.$_[$r]}|% p*ht(1+($a|% v*|%{$_|% l*h}|sort)[-1]))}

ゴルフの少ないテストスクリプト:

$f = {

$a=@{}                              # a hash table for a result
$args|% toCharArray|?{$_-45}|%{     # for each digit from argument strings except a '-'
    if(!$a.$_){$a.$_="","","$_"}    #   create an array if there are no values for the current digit
    $a.$_[++$i-gt4]+=$i             #   append the character to the relative row (0 - top, 1 - bottom) and increment position number
}                                   # the result is a hash table in which the key is a char of a digit and the value is an array of string
                                    # for example, first lines for the first test case:
                                    # @{
                                    #     [char]48: ("2","5","0")
                                    #     [char]49: ("3","","1")
                                    #     [char]50: ("1","67","2")
                                    #     ...
                                    # }
$l=1+($a|% Values|%{$_|% Length}|sort)[-1]      # calc the maximum width of strings
0,2,1|%{                            # for each number 0,2,1
    $r=$_                           # store it as row number
    -join(
        $a.Keys|sort|               # for each keys (digit of the dates) in the sorted order
            %{$a.$_[$r]}|           # push to pipe the relative string
            % padRight $l           # for which to execute the 'padright' method to pad with spaces
    )                               # and finally join the row
}

}

@(

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

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

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

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

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

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

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

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

) | % {
    $d, $expected = $_
    $result = &$f $d

    $d
    $j=0
    $result|%{
        "$($_.trimEnd() -eq $expected[$j].TrimEnd()): |$_|"   # Vertical bars only to see trailing and leading spaces
        $j++
    }
}

出力(末尾と先頭のスペースを見るための垂直バーのみ):

2013-02-27
True: |2  3  1  4     |
True: |0  1  2  3  7  |
True: |5     67    8  |
2015-12-24
True: |2  3  1     4  |
True: |0  1  2  4  5  |
True: |   5  67 8     |
2222-11-11
True: |     1234 |
True: |1    2    |
True: |5678      |
1878-02-08
True: |   1     3  24 |
True: |0  1  2  7  8  |
True: |57    6     8  |
2061-02-22
True: |2   4   1   3   |
True: |0   1   2   6   |
True: |5       678     |
3564-10-28
True: |      1 4 2 3   |
True: |0 1 2 3 4 5 6 8 |
True: |6 5 7         8 |
1111-11-11
True: |1234 |
True: |1    |
True: |5678 |
0123-12-30
True: |1 2 3 4 |
True: |0 1 2 3 |
True: |8 5 6 7 |
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.