그 울타리를 페인트


9

당신은 Tom Sawyer이고 102400m 길이의 울타리를 페인트해야합니다. 운 좋게도, 친구들은 여러 가지를 대가로 당신을 도와 주기로 결정했습니다. 각 친구가 페인트됩니다 L의 시작, 미터 S 컬러와 C . S , L 은 정수의 양이고 1 ≤ C ≤ 97입니다. 지루해지면 각 색상의 미터 수를 결정합니다.

입력

표준 입력에서 입력을 읽습니다. 각 줄에는 위에서 설명한 세 개의 숫자 S , L , C가 포함 됩니다.

출력

출력은 표준 출력에 기록됩니다. 최종 펜스에 나타나는 각 색상에 대해 색상 번호와 색상이 나타나는 횟수를 인쇄하십시오. 색상별로 주문하십시오.

입력 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 Units : en.wikipedia.org/wiki/Imperial_units
Paul R

1
Keith : 오늘 Tom Sawyer가 훨씬 더 현명하고 SI를 사용한다고 가정 할 수 있습니다.
Joey

답변:


2

파이썬, 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트리플 정렬되지 않은 목록으로 울타리의 현재 상태를 나타내는 (실행, 실행의 끝, 색상의 시작). 제너레이터의 랜덤 페인팅은 대형 스와 스를 상당히 자주 오버 페인팅하기 때문에이 목록은 너무 길지 않습니다 (일반적으로 15-40 범위).

1M 예제에서 37 초 안에 실행됩니다.


당신은 G+=[(a,min(b,s),d)]*(a<s)등을 사용 하여 한 줄에 for 루프를 얻을 수 있습니다
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을 알 필요가 없습니다.

@Gareth : 같은 색상을 여러 범위에서 사용하면 복제본이 인쇄 될 것이라고 생각합니다. 어딘가에 미확인이 필요할 것입니다 ...
Keith Randall

당신이 맞습니다 : sorted(set(...))더 이상 개선되지 않는 것이 필요합니다 .

1

하스켈, 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
  • max전화 할 필요가없는 편집 (269 → 261)
  • 페인트를 0으로 줄일 필요가없는 편집 (261 → 251) f

그것은이다 너무 느린 .
Alexandru

코드 골프 야? 코드 골프의 경우 일반적으로 "합리적인 시간"과 같은 제한은 대상 입력 크기의 경우 며칠이 걸릴 수 없음을 의미합니다. 37 초 (다른 답변의 시간)는 괜찮지 만 44 초가 너무 느린 기준이 있습니까? 원한다면 더 빠른 CPU로 시간을 내실 수 있습니다!
MtnViewMark

이 경우 언어 속도가 몇 초 정도 걸립니다. 내가 틀렸다면 나를 수정하지만 Haskell이 Python보다 훨씬 빠르지 않습니까? (그래서 나는 Keith의 솔루션에 투표하지 않았다.) 규칙에 따라 허용되지 않는 것과 비슷한 시간이 걸리는 C 무차별 대입 솔루션이 게시되었습니다.
Alexandru

동일한 시스템에서 측정, 그것은 않습니다 훨씬 빠른 파이썬 솔루션보다 실행합니다. 파이썬 솔루션은 내 컴퓨터에서 133.556 초가 걸립니다. Haskell 솔루션은 3 배 더 빠릅니다. 또한이 Haskell 솔루션은 "브 루트 포스 (brute force)"솔루션이 아니라는 점에 유의하십시오 (단, 벽의 길이에 따라 색상 배열을 만드는 것을 의미한다고 추측합니다)
MtnViewMark

0

펄-148 바이트

펄이 가장 좋은 것 같습니다. 더 짧고 빠르게 코딩하기 쉽습니다. ;)

암호:

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

자바 스크립트, 183 자, 1.3 초

슬프게도 JavaScript가 지원하지 않는 요구 사항의 stdin / out 부분을 잘라 내야했습니다. 대신 파일 업로드에서 입력을 얻습니다 <input>(필자는해야하지만 문자 수에는 포함되지 않습니다).

ungolfed 버전은 다음과 같습니다. 전체 입력 문자열을 가져 오는 기능입니다 ... 모두 14MB입니다! 이것은 1.3 초가 걸리는 것입니다. 골프 버전은 약 두 배의 시간이 걸리지 만 여전히 다른 솔루션보다 뛰어납니다! 흥미롭게도 Firefox보다 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.