Cat pagar itu

9

Anda adalah Tom Sawyer dan Anda harus melukis pagar sepanjang 102400 m. Untungnya, teman Anda memutuskan untuk membantu Anda dalam pertukaran berbagai hal. Setiap teman akan melukis L meter, mulai dari S dengan warna C . S , L adalah jumlah integer meter dan 1 ≤ C ≤ 97. Bosan Anda memutuskan untuk mencari tahu berapa meter dari setiap warna yang Anda miliki.

Memasukkan

Input dibaca dari input standar. Setiap baris berisi tiga angka S , L , C seperti dijelaskan di atas.

Ouput

Output ditulis ke output standar. Untuk setiap warna yang muncul di pagar akhir, cetak nomor warna dan berapa kali itu muncul. Pesan berdasarkan warna.

Contohnya

Masukan 0

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

Keluaran 0

1 4
2 2
5 3

Input 1

 0 100 1
 50 150 2

Output 1

 1 50
 2 150

Input 2

 500 1000 1
 0 2000 2

Keluaran 2

 2 2000

Lebih banyak contoh

Ini generator kecil:

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

Contoh menjalankan:

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

Program Anda harus berjalan dalam waktu yang wajar. Solusi saya berjalan dalam beberapa detik pada contoh terakhir.

Kode terpendek menang.

Termasuk waktu berjalan dan output Anda untuk tes terakhir.

EDIT : Masalah ini tidak dimaksudkan untuk dipaksa, jadi solusi sepele tidak dapat diterima.

Alexandru
sumber
Menurut saya cara paling sederhana (mengalokasikan array, mengisinya, menghitung # setiap warna dalam array, output) akan berjalan dalam waktu yang wajar. Sepertinya Anda bermaksud membuat algoritma untuk menjadi bagian dari tantangan, meskipun - apakah saya salah?
Matius Baca
Saya berpikir bahwa 1000000 ops X 25000 panjang rata-rata = 25 * 10 ^ 9 tidak akan berjalan dalam waktu yang wajar. Saya dapat menambah panjang pagar jika Anda berpikir sebaliknya.
Alexandru
Ah, saya melewatkan inputnya sejuta baris, salah saya.
Matius Baca
1
@Keith: ITYM Imperial Units : en.wikipedia.org/wiki/Imperial_units
Paul R
1
Keith: Saya pikir Anda dapat berasumsi bahwa Tom Sawyer hari ini akan jauh lebih masuk akal dan menggunakan SI.
Joey

Jawaban:

2

Python, 221 239 karakter

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]

Menyimpan Fsebagai daftar tiga kali lipat yang tidak teratur (mulai dari lari, akhir lari, warna) mewakili keadaan pagar saat ini. Karena lukisan acak di dalam generator melebihi jumlah yang cukup besar, daftar ini tidak pernah terlalu lama (biasanya dalam kisaran 15-40).

Berjalan dalam 37 detik pada contoh 1M.

Keith Randall
sumber
Anda dapat menggunakan G+=[(a,min(b,s),d)]*(a<s)dll untuk mendapatkan loop for pada satu baris
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)menyimpan beberapa karakter selama empat baris terakhir Anda, dan menghindari kebutuhan untuk mengetahui angka ajaib 98.
@ Gareth: Saya pikir itu akan mencetak duplikat jika warna yang sama digunakan oleh lebih dari satu rentang. Perlu ada uniqifikasi di sana di suatu tempat ...
Keith Randall
Anda benar: itu perlu sorted(set(...))yang tidak lagi merupakan peningkatan.
1

Haskell, 251 261 269 294 karakter

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

Ada sesuatu yang tidak beres tentang ini karena terlalu banyak waktu dan tumpukan ... Tapi itu menghasilkan jawaban yang benar:

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

  • Edit (294 → 269) replicatedan grouphanya cara yang efisien untuk menghitung cat, dan mengambil kode kurang dari fungsi kustoms
  • Sunting (269 → 261) tidak perlu maxmenelepon
  • Sunting (261 → 251) tidak perlu untuk menghapus cat 0 in f
MtnViewMark
sumber
Itu terlalu lambat .
Alexandru
Ini kode-golf, bukan? Untuk kode-golf, biasanya batasan seperti "waktu yang masuk akal" berarti, bahwa untuk ukuran input target, tidak dapat memakan waktu berhari-hari. Apakah ada beberapa kriteria di mana 37 detik (waktu jawaban lain) tidak apa-apa, tetapi 44 detik terlalu lambat? Saya bisa mengatur waktu saya menggunakan CPU yang lebih cepat jika Anda mau!
MtnViewMark
Dalam hal ini perlu waktu beberapa detik * pelambatan bahasa. Perbaiki saya jika saya salah, tetapi bukankah Haskell jauh lebih cepat daripada Python? (Itulah sebabnya saya tidak memilih solusi Keith). Ada solusi brute force C yang dipasang pada waktu yang sama yang, menurut aturan, tidak diizinkan.
Alexandru
Diukur pada mesin yang sama, itu tidak berjalan lebih cepat daripada solusi Python. Solusi Python membutuhkan 133,556 detik pada mesin saya. Solusi Haskell adalah 3x lebih cepat. Juga, perhatikan bahwa solusi Haskell ini bukan solusi "brute force" (yang saya duga maksud Anda hanya dengan membangun serangkaian warna sepanjang dinding.)
MtnViewMark
0

Perl - 148 byte

Tampaknya Perl adalah yang terbaik untuk dimainkan. kode mudah lebih pendek dan lebih cepat. ;)

kode:

#!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

waktu:

time ./gen 1000000 | perl paint.pl
...
real    0m9.767s
user    0m10.117s
sys 0m0.036s
Hojung Youn
sumber
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
aero
sumber
0

JavaScript, 183 karakter, 1,3 detik

Sayangnya, saya harus memotong bagian stdin / out dari persyaratan, yang tidak didukung JavaScript. Alih-alih, saya mendapatkan input dari unggahan file <input>(yang saya tidak hitung dalam hitungan char saya, walaupun mungkin saya harus).

Ini adalah versi yang tidak diserang. Ini adalah fungsi yang mengambil string input penuh ... semua 14MB itu! Ini adalah yang membutuhkan 1,3 detik; versi golf memakan waktu sekitar dua kali lebih lama - tetapi masih mengalahkan solusi lain! Menariknya, ini dua kali lebih cepat di Firefox daripada di Chrome. Demo langsung di sini .

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

Dan ini versi golfnya.

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

tangkapan layar

Casey Chu
sumber