ทาสีรั้วนั้น


9

คุณเป็นทอมซอเยอร์และคุณต้องทาสีรั้วยาว 1,600 เมตร โชคดีที่เพื่อนของคุณตัดสินใจช่วยคุณในการแลกเปลี่ยนสิ่งต่าง ๆ เพื่อนแต่ละคนจะวาดLเมตรเริ่มต้นจากSมีสีC S , Lคือจำนวนเต็มของเมตรและ 1 ≤ C ≤ 97 การเริ่มเบื่อคุณตัดสินใจที่จะหาว่าคุณมีกี่เมตรของแต่ละสี

อินพุต

อินพุตถูกอ่านจากอินพุตมาตรฐาน แต่ละบรรทัดมีสามตัวเลขS , L , Cตามที่อธิบายไว้ข้างต้น

ouput

เอาต์พุตถูกเขียนไปยังเอาต์พุตมาตรฐาน สำหรับแต่ละสีที่ปรากฏบนรั้วสุดท้ายพิมพ์หมายเลขสีและจำนวนครั้งที่ปรากฏ เรียงตามสี

ตัวอย่าง

อินพุต 0

                           ..............
0 3 1                      111...........
2 4 2                      112222........
1 2 3                      133222........
0 4 1                      111122........
7 3 5                      111122.555....

เอาท์พุท 0

1 4
2 2
5 3

อินพุต 1

 0 100 1
 50 150 2

เอาท์พุท 1

 1 50
 2 150

อินพุต 2

 500 1000 1
 0 2000 2

เอาท์พุท 2

 2 2000

ตัวอย่างเพิ่มเติม

นี่คือเครื่องกำเนิดไฟฟ้าขนาดเล็ก:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>


/* From http://en.wikipedia.org/wiki/Random_number_generation */
unsigned m_w;
unsigned m_z;

unsigned get_random()
{
  m_z = 36969 * (m_z & 65535) + (m_z >> 16);
  m_w = 18000 * (m_w & 65535) + (m_w >> 16);
  return (m_z << 16) + m_w;  /* 32-bit result */
}

int main(int argc, char **argv)
{
  int i;

  assert(argc == 2);
  m_w = 0xbabecafe;
  m_z = atoi(argv[1]);

  i = 10;
  while (i--);
    get_random();

  i = atoi(argv[1]);
  while (i--) {
    int s = (int) ((get_random() << 8) % 102397);
    int l = (int) ((get_random() << 8) % (102397 - s));
    int c = (int) ((get_random() << 8) % 97 + 1);
    printf("%d %d %d\n", s, l, c);
  }

  return 0;
}

ตัวอย่างการวิ่ง:

$ ./gen 1 | ./paint
6 535
$ ./gen 10 | ./paint
28 82343
36 3476
41 1802
49 4102
82 1656
$ ./gen 100 | ./paint
2 2379
22 17357
24 4097
25 1051
34 55429
42 9028
45 9716
66 1495
71 196
85 640
97 706
$ ./gen 1000 | ./paint
16 719
26 29
28 24
33 1616
55 371
65 35
69 644
74 16
84 10891
86 36896
87 50832
89 19
$ ./gen 10000 | ./paint
3 800
6 5712
14 3022
17 16
26 1
29 18770
31 65372
37 387
44 40
49 37
50 93
55 11
68 278
70 19
71 64
72 170
77 119
78 6509
89 960
97 15
$ ./gen 100000 | ./paint
2 6
8 26
12 272
24 38576
26 1
34 1553
35 8
36 19505
43 2
45 11
46 2
47 9
49 27339
50 139
53 3109
69 11744
92 89
$ ./gen 1000000 | ./paint
1 1
3 4854
6 523
13 1
16 11
18 416
22 7
24 3920
25 96
31 10249
32 241
37 1135
45 10
57 758
62 2348
65 11
66 7422
78 6
85 13361
87 3833
88 187
91 46
93 7524
96 45436

โปรแกรมของคุณจะต้องทำงานในเวลาที่เหมาะสม โซลูชันของฉันทำงานในไม่กี่วินาทีในตัวอย่างสุดท้าย

รหัสที่สั้นที่สุดชนะ

รวมเวลาทำงานและผลลัพธ์ของคุณสำหรับการทดสอบครั้งสุดท้าย

แก้ไข : ปัญหานี้ไม่ได้มีวัตถุประสงค์เพื่อเป็นสัตว์เดรัจฉานบังคับดังนั้นวิธีแก้ปัญหาเล็กน้อยไม่เป็นที่ยอมรับ


ดูเหมือนว่าวิธีที่ง่ายที่สุด (จัดสรรอาร์เรย์เติมนับจำนวน # ของแต่ละสีในอาร์เรย์ผลลัพธ์) จะทำงานในเวลาที่เหมาะสม ดูเหมือนว่าคุณตั้งใจจะคิดอัลกอริทึมให้เป็นส่วนหนึ่งของความท้าทาย - ฉันผิดหรือเปล่า?
Matthew อ่าน

ฉันคิดว่า 1000000 ops X ความยาวเฉลี่ย 25000 = 25 * 10 ^ 9 จะไม่ทำงานในเวลาที่เหมาะสม ฉันสามารถเพิ่มความยาวรั้วได้ถ้าคุณคิดเป็นอย่างอื่น
Alexandru

อาฉันพลาดว่าอินพุตเป็นล้านเส้นแย่ไปหน่อย
Matthew อ่าน

1
@Keith: หน่วย ITYM Imperial : en.wikipedia.org/wiki/Imperial_units
Paul R

1
Keith: ฉันคิดว่าคุณสามารถสันนิษฐานได้ว่า Tom Sawyer วันนี้จะมีเหตุผลมากกว่านี้และใช้ SI
Joey

คำตอบ:


2

Python 221 239ตัวอักษร

import sys
F=[]
for L in sys.stdin:s,l,c=map(int,L.split());F=sum([[(a,min(b,s),d)]*(a<s)+[(max(a,s+l),b,d)]*(b>s+l)for a,b,d in F],[(s,s+l,c)])
C=[0]*98
for a,b,c in F:C[c]+=b-a
for c in range(98):
 if C[c]:print c,C[c]

เก็บFเป็นรายการที่ไม่ได้เรียงลำดับของ triples (start of run, end of run, color) ที่แสดงสถานะปัจจุบันของรั้ว เนื่องจากภาพวาดแบบสุ่มในเครื่องกำเนิดไฟฟ้ามีค่ามากเกินไปทำให้เกิดการ swathes ค่อนข้างบ่อยรายการนี้จึงไม่นานเกินไป (โดยทั่วไปจะอยู่ในช่วง 15-40)

ทำงานใน 37 วินาทีในตัวอย่าง 1M


คุณสามารถใช้G+=[(a,min(b,s),d)]*(a<s)ฯลฯ เพื่อรับวงในหนึ่งบรรทัด
gnibbler

for C in sorted(f[2] for f in F):print C,sum(b-a for a,b,c in F if c==C)บันทึกอักขระสองสามตัวในสี่บรรทัดสุดท้ายของคุณและหลีกเลี่ยงความจำเป็นในการรู้เวทมนตร์หมายเลข 98

@ กาเร็ ธ : ฉันคิดว่ามันจะพิมพ์ซ้ำกันหากใช้สีเดียวกันมากกว่าหนึ่งช่วง จะต้องมีการ uniqification ในที่ใดที่หนึ่ง
Keith Randall

คุณพูดถูก: มันจะต้องเป็นsorted(set(...))สิ่งที่ไม่มีการปรับปรุงอีก

1

Haskell, 251 261 269 294ตัวอักษร

import Data.List
w@(y@(f,d,e):z)§x@[a,b,c]|e<=d=z§x|a+b>d=(f,d,e`min`a):((f,a+b,e):z)§x
w§[a,b,c]=(c,a,a+b):w
r(c,a,b)=replicate(b-a)c
f l=shows(l!!0)" "++shows(length l)"\n"
main=interact$(>>=f).group.(>>=r).sort.foldl'(§)[].map(map read.words).lines

บางสิ่งบางอย่างไม่ถูกต้องเกี่ยวกับสิ่งนี้เนื่องจากใช้เวลาและสแต็คมากเกินไป ... แต่มันให้คำตอบที่ถูกต้อง:

$> ghc -O3 --make -rtsopts -with-rtsopts -K32m 3095-PaintTheFence.hs 
Linking 3095-PaintTheFence ...

$> ./3095-gen 1000000 | time ./3095-PaintTheFence
1 1
3 4854
6 523
13 1
16 11
18 416
22 7
24 3920
25 96
31 10249
32 241
37 1135
45 10
57 758
62 2348
65 11
66 7422
78 6
85 13361
87 3833
88 187
91 46
93 7524
96 45436
       43.99 real        43.42 user         0.46 sys

  • แก้ไข (294 → 269) replicateและgroupเป็นวิธีที่มีประสิทธิภาพเช่นเดียวกับการนับสีและใช้รหัสน้อยกว่าฟังก์ชั่นที่กำหนดเองs
  • แก้ไข (269 → 261) ไม่จำเป็นต้องmaxโทร
  • แก้ไข (261 → 251) ไม่จำเป็นต้องเลือกสี 0 f

มันเป็นช้าเกินไป
Alexandru

มันเป็นรหัสกอล์ฟใช่ไหม สำหรับโค้ดกอล์ฟมักจะมีข้อ จำกัด เช่น "เวลาที่เหมาะสม" หมายความว่าสำหรับขนาดอินพุตเป้าหมายมันใช้เวลาไม่กี่วัน มีเกณฑ์บางอย่างหรือไม่ที่เวลา 37 วินาที (เวลาของคำตอบอื่น ๆ ) ก็โอเค แต่ 44 วินาทีช้าเกินไป? ฉันสามารถใช้เวลากับซีพียูที่เร็วกว่านี้ได้ถ้าคุณต้องการ!
MtnViewMark

ในกรณีนี้ควรใช้เวลาสองสามวินาทีในการชะลอตัวของภาษา แก้ไขให้ถูกต้องหากฉันผิด แต่ Haskell นั้นเร็วกว่า Python ไม่มากใช่ไหม (ซึ่งเป็นสาเหตุที่ฉันไม่ลงคะแนนวิธีแก้ปัญหาของ Keith) มีการแก้ปัญหากำลังเดรัจฉาน C ที่โพสต์ในเวลาเดียวกันซึ่งตามกฎไม่ได้รับอนุญาต
Alexandru

วัดในเครื่องเดียวกันก็ไม่ทำงานได้เร็วกว่าวิธีการแก้ปัญหาหลาม โซลูชัน Python ใช้เวลา 133.556 วินาทีในเครื่องของฉัน โซลูชัน Haskell เร็วขึ้น 3 เท่า นอกจากนี้โปรดทราบว่าโซลูชัน Haskell นี้ไม่ใช่โซลูชัน "กำลังดุร้าย" (ซึ่งฉันคาดเดาว่าคุณหมายถึงเพียงสร้างอาร์เรย์สีตามความยาวของกำแพง)
MtnViewMark

0

Perl - 148 ไบต์

ดูเหมือนว่า Perl เป็นเกมที่ดีที่สุดในการเล่น รหัสง่ายสั้นและเร็วขึ้น ;)

รหัส:

#!perl -n
($a,$b,$c)=split;substr($s,$a,$b,chr($c)x$b)}BEGIN{$s="z"x102400}{$s=~s/([^z])\1*/$H{$1}+=length$&/ge;print ord," $H{$_}
"for sort keys%H

เวลา:

time ./gen 1000000 | perl paint.pl
...
real    0m9.767s
user    0m10.117s
sys 0m0.036s

0
$ cat input.txt
0 3 1
2 4 2
1 2 3
0 4 1
7 3 5

$ cat input.txt  | perl -anE '@a[$F[0]..$F[0]+$F[1]]=($F[2])x$F[1];END{$i[$_]++for@a;$i[$_]&&say"$_ $i[$_]"for 1..$#i}'
1 4
2 1
5 3


$ cat input2.txt
500 1000 1
0 2000 2

$ cat input2.txt  | perl -anE '@a[$F[0]..$F[0]+$F[1]]=($F[2])x$F[1];END{$i[$_]++for@a;$i[$_]&&say"$_ $i[$_]"for 1..$#i}'
2 2000

0

JavaScript, 183 ตัวอักษร, 1.3 วินาที

น่าเศร้าที่ฉันต้องตัดส่วน stdin / out ของข้อกำหนดซึ่ง JavaScript ไม่รองรับ แต่ฉันได้รับข้อมูลจากการอัปโหลดไฟล์<input>แทน (ซึ่งฉันไม่ได้นับในจำนวนถ่านของฉันแม้ว่าฉันอาจจะควร)

นี่คือเวอร์ชั่นที่ไม่ดี มันเป็นฟังก์ชั่นที่รับสายป้อนข้อมูลเต็ม ... ทั้งหมด 14MB ของมัน! นี่คืออันที่ใช้เวลา 1.3 วินาที; เวอร์ชัน golfed ใช้เวลานานกว่าสองเท่า - แต่มันก็ยังคงเป็นทางออกอื่น ๆ ! ที่น่าสนใจมันเร็วกว่า Firefox เป็นสองเท่า สาธิตอาศัยอยู่ที่นี่

function Q(input) {

    var c = [];
    var l = input.trim().split(/\s/g);
    input = null
    var length = l.length;

    // Loop through each meter of the wall...
    for (var i = 0; i <= 102400; i++) {

        // ...and loop through each of the friends, finding
        // the last one who painted this meter...
        for (var j = length; j > 0; ) {
            j -= 3;

            // Start = +l[j]
            // Length = +l[j + 1]
            // Color = +l[j + 2]

            var S = +l[j];      
            if (S <= i && +l[j + 1] + S > i) {

                // ...and incrementing the color array.
                var C = +l[j + 2];
                if (!++c[C])
                    c[C] = 1;

                break;
            }
        }
    }

    console.log(c.map(function (a,b) {return b + ' ' + a}).filter(function (a) { return a }).join('\n'));
}

และนี่คือเวอร์ชั่นของกอล์ฟ

function G(i){l=i.trim(c=[]).split(/\s/)
for(i=0;i<102401;i++)for(j=l.length;j>0;)if(l[j-=3]<=i&&i-l[j+1]<l[j]){if(!++c[l[j+2]])c[l[j+2]]=1
break}for(k in c)console.log(k+' '+c[k])}

ภาพหน้าจอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.