แปลงวันที่เป็นสัญกรณ์ xkcd


26

ใน xkcd ของเขาเกี่ยวกับรูปแบบวันที่มาตรฐาน ISO 8601 Randall ดักในสัญกรณ์ทางเลือกที่ค่อนข้างอยากรู้:

ป้อนคำอธิบายรูปภาพที่นี่

ตัวเลขขนาดใหญ่คือตัวเลขทั้งหมดที่ปรากฏในวันที่ปัจจุบันตามลำดับปกติและตัวเลขขนาดเล็กเป็นดัชนีที่อิงกับ 1 ครั้งของการเกิดขึ้นของตัวเลขนั้น 2013-02-27ดังนั้นตัวอย่างข้างต้นหมายถึง

ลองกำหนดการแสดง ASCII สำหรับวันดังกล่าว บรรทัดแรกมีดัชนี 1 ถึง 4 บรรทัดที่สองประกอบด้วยตัวเลข "ใหญ่" บรรทัดที่สามประกอบด้วยดัชนี 5 ถึง 8 หากมีดัชนีหลายรายการในสล็อตเดียวรายการเหล่านั้นจะอยู่ติดกันตั้งแต่ขนาดเล็กที่สุดไปหามากที่สุด หากมีmดัชนีมากที่สุดในช่องเดียว (เช่นในหลักเดียวกันและในแถวเดียวกัน) แต่ละคอลัมน์ควรมีm+1อักขระกว้างและจัดชิดซ้าย:

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

ดูความท้าทายสำหรับคู่หูสำหรับการแปลงฝั่งตรงข้าม

ความท้าทาย

ให้วันที่ ISO 8601 ( YYYY-MM-DD) ส่งออกสัญกรณ์วันที่ xkcd ที่เกี่ยวข้อง

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

ทุกปีจาก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`
`

น้อย golfed

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>


โอ้กรณีทดสอบเพิ่มเติมที่ดี ฉันจะเพิ่มมันเข้าไปในความท้าทายทั้งสอง
Martin Ender

4

Ruby, 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

Python 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;}

Ungolfed:

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

Ungolfed (เล็กน้อย)

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ตัวแปรหรือไม่
เดนนิส

@Dennis: อืม ฉันสงสัยว่าทำไมฉันไม่เคยคิดอย่างนั้น อาจจะเป็นเพราะผมก็คืการรักษา''.join(...)เป็นjoin('',...)ที่จะต้องมีการ "บันทึก" เป็นหน้าที่แทน
ทิม Pederick

1
ผมคิดว่าอาจจะเป็น+=[i] +=i,
Jonathan Frech

1
return '\n'return'\n'->
Jonathan Frech

1
@TimPederick คุณแน่ใจหรือไม่ (สังเกตเครื่องหมายจุลภาค!)
Jonathan Frech

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]))}

สคริปต์ทดสอบ golfed น้อย:

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