당신은 골프 골프 수 있습니까?


53

임의의 18 홀 골프 코스를 생성해야합니다.

출력 예 :

[3 4 3 5 5 4 4 4 5 3 3 4 4 3 4 5 5 4]

규칙 :

  • 프로그램은 정확히 18 홀에 대한 홀 길이 목록을 출력해야합니다
  • 각 구멍의 길이는 3, 4 또는 5 여야합니다
  • 전체 코스의 홀 길이는 최대 72
  • 프로그램은 가능성이 0이 아닌 가능한 모든 구멍 구성을 생성 할 수 있어야합니다 (각 구성의 확률은 같을 필요는 없지만,이 경우 추가 칭찬을 자유롭게 요구하십시오)

3
44152809 솔루션을 확인하십시오?
baby-rabbit

1
나도 정확한 수의 솔루션에 대해 궁금하지만 4,400 만 이상이어야한다고 생각합니다 ... (수학자는 아니지만 : | 1 (5) / 1 (3) = 306 가능성 (17 * 18) 2 (5) / 2 (3) = 69360 poss (17 * 17 * 16 * 15) | 3 (5) / 3 (3) = 11182080 poss (16 * 16 * 16 * 15 * 14 * 13) | 않습니다 ?이 정확
NRGdallas

11
@ baby-rabbit : 무차별 강제 열거로 44,152,809 솔루션을 확인할 수 있습니다. 평균 정확히 버젼 :이를 직접 방식으로 계산 될 수있다 4, 유일한 가능성은 3, 4또는 5, 가능한 해결책 클래스이다 { no 3's or 5's, one 3 and one 5, two 3's and two 5's,, ... nine 3's and nine 5's}. 이것은로 계산할 수 있습니다 nCr(18,0)*nCr(18,0) + nCr(18,1)*nCr(17,1) + nCr(18,2)*nCr(16,2) + ... + nCr(18,9)*nCr(9,9) = 44,152,809. 이는 11.4%가능한 모든 조합 중 유효한 솔루션 임을 의미 합니다 (44,152,809 / 3^18).
mellamokb

2
sum(factorial(18)/factorial(x)/factorial(y)/factorial(z) for x in range(25) for y in range(25) for z in range(25) if 3*x+4*y+5*z == 72 and x+y+z == 18)제공44152809L
Sanjeev Murty

답변:


29

k ( 18 17 16 자)

원래의 접근법으로 돌아가서 개선을위한 CS의 공로.

(+/4-){3+18?3}/0

J 솔루션과 동일한 방법, CS에 대한 H / T와 같은 다른 접근 방식 (17 자)

4+a,-a:9?2 -18?18

구 버전:

(72-+/){18?3+!3}/0

스택 오버플로에 취약하지 않으며 고정 된 공간에서 실행됩니다.


CS에 대한 H / T 란 무엇입니까?
Gareth


이 프로그램을 통해 K 인터프리터에서 버그 를 발견 할 수 있었습니다. 감사합니다! 나는 이전에 nilads가 단일 인수에 적용될 수 있음을 알지 못했습니다.
JohnE


15

J, 20 18 17 자

(?~18){4+(,-)?9#2

이것은 9 개의 임의의 숫자가 0 또는 1이고 추가되기 전에 부정되는 것을 제외하고는 이전 답변과 같은 방식으로 작동합니다. 이 많은이 의미 -1가 있기 때문에 S 1들. 4를 더하면 3s, 4s 및 5s 의 목록이 매번 최대 72 개까지 추가됩니다.

이전 답변 :

({~?~@#)3+(,2-])?9#3

처음 9 개의 구멍을 무작위로 생성 한 ?9#3다음 복사하여 뒤집어서 (,2-])(3을 5로, 5를 3으로 3으로 변환) 최종 9를 생성합니다. 이렇게하면 전체가 72 개가됩니다 (3마다 일치하는 5가 있으므로 구멍 당 평균 총계는 4와 4x18 = 72입니다. 그런 다음 ({~?~@#)모든 조합이 가능하도록 결과 를 무작위로 섞습니다 .


실제로 당신은 {3,5,4,4,4 ...}를 생성하지 않을 것입니다. 당신은 전체 결과를 뒤섞는 것이 더 좋습니다
ratchet freak

@rachetfreak 좋은 지적입니다. 지금 편집하겠습니다.
Gareth

13

MS-DOS에서 16 비트 x86 기계 코드-45 바이트

16 진 덤프 :

0E5F576A12595188ECE44088C3E44130D8240374F400C4AAE2EF595E80FC2475DFAC0432CD29B020CD29E2F5C3

Base64 코드 바이너리 :

Dl9XahJZUYjs5ECIw+RBMNgkA3T0AMSq4u9ZXoD8JHXfrAQyzSmwIM0p4vXD

주석이 포함 된 실제 소스 코드 :

 bits 16
 org 0x100

again:
 push cs               ; Save whatever CS we get.
 pop di                ; Use CS:DI as our course buffer..
 push di               ; Save for later use in the print loop
 push 18               ; We need 18 holes for our golf course.
 pop cx                ; ch = 0, cl = 18.
 push cx               ; Save for later use.
 mov ah, ch            ; Zero out ah.
generate_course:
 in al, 0x40           ; Port 0x40 is the 8253 PIT Counter 0.
 mov bl, al            ; Save the first "random" value in bl.
 in al, 0x41           ; Port 0x41 is the 8253 PIT Counter 1.
 xor al, bl            ; Add some more pseudo randomness.
 and al, 3             ; We only need the two lower bits.
 jz generate_course    ; If zero, re-generate a value, since we need only 3, 4, 5 holes.
 add ah, al            ; Sum in ah register.
 stosb                 ; Store in the course buffer.
 loop generate_course  ; Loop for 18 holes.
 pop cx                ; cx = 18.
 pop si                ; si = course buffer.
 cmp ah, 36            ; 72 holes?
 jne again             ; No, re-generate the whole course.

print:                 ; Yup, we have a nice course.
 lodsb                 ; Load the next hole.
 add al, '2'           ; Add ASCII '2' to get '3', '4' or '5'
 int 0x29              ; Undocumented MS-DOS print function.
 mov al, ' '           ; Print a space too for better readability.
 int 0x29              ; Print the character.
 loop print            ; Print the whole course.
 ret                   ; Return to the beginning of the PSP where a INT 0x20 happen to be.

nasm 18h.asm -o 18h.com32 비트 Windows 버전의 MS-DOS (또는 Dosbox) 또는 NTVDM을 사용하여 컴파일 하고 실행하십시오.

샘플 출력 :

4 5 4 5 4 5 3 4 3 4 3 4 4 5 4 3 5 3

3
사랑 어셈블러 ...
woliveirajr

13

매스 매 티카 71 68 66 60

Tally의 제안에 의해 6 개의 문자가 저장됩니다.

RandomSample@RandomChoice@IntegerPartitions[72, {18}, {3, 4, 5}]

{5, 4, 3, 3, 5, 3, 5, 5, 3, 3, 4, 5, 3, 5, 4, 4, 5, 3}

가능한 모든 결과는 가능하지만 똑같이 가능하지는 않습니다.


분석

IntegerPartitions[72, {18}, {3, 4, 5}]

72는 3, 4 및 5로 구성된 18 개의 요소로 가능한 10 개의 가능한 파티션 (순열이 아닌 조합)을 생성합니다.

파티션


RandomChoice 그중 하나를 선택합니다.

RandomSample 해당 선택의 순열을 반환합니다.


Hehe, 나는 RandomInteger 대신 RandomChoice 만 사용하여 거의 똑같은 대답을 게시하려고했습니다. 그렇게하면 더 많은 캐릭터를 면도 할 수 있다고 생각합니다.
Tally

탈리, 고마워 당신의 제안은 도움이되었습니다.
DavidC

8

제 41 화

x=0;while(sum(x)!=72)x=sample(3:5,18,T);x

# [1] 5 3 5 3 3 3 3 3 5 4 5 4 5 4 4 5 5 3

알고리즘은 @sgrieve와 유사합니다.


위의 @sgrieve와 같은 문제-18 홀에서 넘어지지 않는 것은 없습니다.
gt6989b

3
문제는 아닙니다.이 경우 샘플 명령은 항상 18 개의 값을 생성합니다.
Sgrieve

8

GolfScript (26 자)

{;0{3rand.3+@@+(}18*])}do`

Ilmari의 솔루션과 명백한 차이점이 있지만 명백한 차이점도 있습니다. 특히, 나는 평균 파가 4라는 사실을 이용하고 있습니다.


젠장, 그러나 확실히 루프 조건이있는 영리한 트릭입니다. 나는 {;0{3.rand+.@+}18*])72-}do나 자신을 생각해 냈지만 거기에서 그것을 더 짧게 얻는 방법을 알 수 없었다. +1.
Ilmari Karonen

7

파이썬 77

암호

from numpy.random import*;l=[]
while sum(l)!=72:l=randint(3,6,18)
print l

산출

[3 4 4 5 3 3 3 5 4 4 5 4 5 3 4 4 5 4]

수입품은 실제로이 솔루션을 죽입니다. numpy를 사용하여 3에서 5 사이의 18 개의 숫자를 생성하고 목록의 합계가 72가 될 때까지 목록을 계속 생성합니다.


18 홀을 생성하기 전에 프로그램이 72 웰에 도달하지 못하게하는 것은 무엇입니까? 72를 건너 뛰는 것을 막는 것은 무엇입니까?
DavidC

3
코드는 항상 18 홀을 생성 한 다음 합계가 72와 같은지 확인합니다. 예를 들어, 16 홀 이후의 합계가 72 인 경우에는 합계를 72 이상으로 밀고 테스트에 실패하여 다른 2 홀을 생성합니다.
Sgrieve

7

GolfScript, 27 자

{;18{3.rand+}*].{+}*72-}do`

Sgrieve의 Python 솔루션과 동일한 거부 샘플링 방법을 사용합니다. 따라서 모든 유효한 출력은 실제로 동일하게 가능합니다.


7

Q (25 자)

원본 (27)

while[72<>sum a:18?3 4 5];a

샘플 출력

4 4 3 3 4 5 4 3 4 5 5 3 5 5 5 4 3 3

약간 짧음 (25)

{72<>sum x}{x:18?3 4 5}/0

7

자바 스크립트, 66 64 61 자

TwoScoopsofPig (PHP)와 Joe Tuskan (JS)에서 많은 영감을 받았습니다.

for(a=[s=0];s!=72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0);a

for(a=[s=0];s-72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0)a

for(a=s=[];s;)for(i=18,s=72;i;s-=a[--i]=Math.random()*3+3|0)a

2
s!=72s-72하나의 문자를 저장할 수 있습니다 . 그리고 마지막 세미콜론 ;a은 다른 문자에도 필요하지 않습니다.
Joe Tuskan

나는 for(i=x;i;i--)2 문자를 저장하기 전에 본 적이 없다 for(i=0;i<x;i++). 감사합니다!
Math chiller

7

파이썬 2, 70 바이트

from random import*
print sample(([3,5]*randint(0,9)+[4]*99)[:18],18)
편집하다:

Sgrieve 솔루션과 비슷한 또 다른 것이 있습니다.

파이썬 2, 73 바이트 + 동일 확률

from random import*
a=[]
while sum(a)-72:a=sample([3,4,5]*18,18)
print a

5

자바 스크립트, 116 99 65 바이트

for(i=0,h=[];i<18;)h[i++]=5;while(h.reduce(function(a,b){return a+b})!=72){i=Math.random()*18|0;h[i]=[3,4,4][i%3]}h;

h=[0];while(h.reduce(function(a,b){return a+b})-72)for(i=0;i<18;h[i++]=[3,4,5][Math.random()*3|0])h

while(i%18||(a=[i=s=0]),s+=a[i++]=Math.random()*3+3|0,s-72|i-18)a

1
Chrome 21에서 이것을 실행하면을 얻습니다 i is not defined.
mellamokb

5

파이썬 128 개 120 116 문자

import random,itertools
random.choice([g for g in itertools.product(*(range(3,6)for l in range(18))) if sum(g)==72])

import 명령문은 여전히 ​​길이 킬러입니다 (네임 스페이스에서 2 개의 함수를 가져 오기 위해 23 자만 사용)

이 코드는 먼저 가능한 모든 솔루션을 무작위로 선택하기 전에 가능한 모든 솔루션을 평가하므로 가까운 미래에 결과가 필요하지 않기를 바랍니다. 아마도이 문제에 대한 가장 느린 해결책 일 것입니다.

각 구성의 동일한 확률에 대해 추가 칭찬을 주장합니다 ...


4
import random,itertools
grawity

당신이 옳습니다.
Adrien Plisson

기타 팁 : import random as r,itertools as i다음 사용 r하고 i대신 randomitertools. 사용 18*[0]대신 range(18)하고, [3,4,5,6]대신 range(3,6):
알렉스 L

나는 파이썬 3을 사용하고 있습니다 : 목록 이해는 생성기이며 길이가 없으므로 choice()함수 와 함께 사용하지 못합니다 . 그 ...이 코드가 너무 느리게 만드는 것 또한의
아드 Plisson

1
죄송합니다, 목록 이해와 생성기 표현을 엉망으로 만들었습니다 (일반적으로 반복기의 성능이 좋기 때문에 생성기 표현을 선호하는 목록 이해를 피합니다). 실제로 python3에서도 여전히 일부 문자를 제거 할 수 있습니다 ... @Alex가 올바르게했습니다.
Adrien Plisson

4

PHP-77 문자

<?while(array_sum($a)!=72){for($i=0;18>$i;){$a[++$i]=rand(3,5);}}print_r($a);

Sgrieve의 솔루션과 마찬가지로 18 홀 목록을 작성하고 총 파를 확인한 후 인쇄하거나 거부하고 다시 시도합니다. 이상하게도 두 솔루션의 길이는 같습니다.

오히려 PHP는 이름이 간결한 배열 함수를 제공하지 않습니다. Array_sum과 print_r이 나를 죽이고 있습니다. 제안을 환영합니다.


1
여기서 중괄호는 필요하지 않으며 합은 일 수 있습니다 +=. <?while($s!=72)for($s=$i=0;18>$i;$s+=$a[++$i]=rand(3,5));print_r($a);
grawity

유용합니다-논리 for 루프 호출 넣지 않았다고 생각했습니다 .
TwoScoopsofPig

고마워 –하지만 실제로 "중괄호가 필요하지 않습니다"라는 의미는 아닙니다. 당신은 원래 코드에서도 그것들을 제거 할 수있었습니다 :while(array_sum($a)!=72)for($i=0;18>$i;)$a[++$i]=rand(3,5);
grawity

직장에서 골프를 치고 있기 때문에 php.ini보다 더 엄격하지는 않습니다. 중괄호가 누락되거나 일치하지 않는다는 불만은 없습니다. 일반적으로 나는 것입니다.
TwoScoopsofPig

이상하다; E_ALL | E_STRICT를 사용한 5.4.7은의 누락에 대해 절대로 불평하지 않습니다 {}(PHP 구문이 명시 적으로 허용하기 때문에).
grawity

4

루비 1.9 (62 자)

a=Array.new(18){[3,4,5].sample}until(a||[]).inject(:+)==72
p a

레일 (55 문자)

에서 $ rails c(모든 레일 폴더) REPL :

a=Array.new(18){[3,4,5].sample}until(a||[]).sum==72
p a

참고 : shuffle[0]대신 대신 사용하면 Ruby 1.8에서 작동합니다 sample.


2
주변에 공백이 필요합니까?
Kaz

@Kaz 당신 말이 맞아요, 필요하지 않습니다. :) 지금 62 문자.
js-coder

1
(1..18).map{rand(3)+3}무작위 배열을 얻는 데 사용할 수 있습니다 ;)
epidemian

4

리스프 ( 78 개 69 문자)

(do ((c () (mapcar (lambda (x) (+ 3 (random 3))) (make-list 18))) ((= (apply '+ c) 72) c))

(do((c()(loop repeat 18 collect(+ 3(random 3)))))((=(apply'+ c)72)c))

Sgrieve의 Python 솔루션과 비슷합니다.

c를 NIL로 시작하고, 합계 72를 확인하고, c의 do"증가 함수"는 3과 5 사이에서 18 개의 숫자 목록을 생성하고 다시 72를 확인하고, 거품을 내고, 헹구고, 반복합니다.

보고 참신 do하고 loop친절하게 함께 골프를 재생할 수 있습니다.


3

C (123 자)-효율성을위한 노력

wc를 통해 파이프하면 10 초 내에 모든 44152809 솔루션이 생성됩니다 ...

char s[19];g(d,t){int i;if(d--){for(i=51,t-=3;i<54;i++,t--)if(t>=3*d&&t<=5*d)s[d]=i,g(d,t);}else puts(s);}main(){g(18,72);}

오, 글쎄-질문을 제대로 읽지 못했지만 모든 솔루션을 생성하고 동일한 확률로 무작위 솔루션을 선택하는 것은 스크립팅 연습입니다. : P


3

클로저-55

(shuffle(mapcat #([[4 4][3 5]%](rand-int 2))(range 9)))

꽤 재미있는 트릭 .... 문제의 수학적 구조를 이용하여 5 개의 파홀과 정확히 같은 3 개의 파홀이 있어야합니다.


3

파이썬 83

import random as r;x=[]
while sum(x)!=72:x=[r.randint(3,5) for i in 18*[0]]
print x

Sgrieve의 솔루션과 같지만, 숫자가없는

골프 Adrien Plisson의 솔루션 : 120-> 108 문자

import random as r,itertools as i
r.choice([g for g in i.product(*([3,4,5,6]for l in 18*[0]))if sum(g)==72])

MATLAB 53

x=[];
while sum(x)~=72
x=3+floor(rand(1,18)*3);
end
x

출력 :

x = 4 34444 5444 5678 5 5


좋은 접근 방법이지만 randi([3,5],1,18)대신 입력하여 4 바이트를 절약 할 수 있습니다.3+floor(rand(1,18)*3)
brainkz

3

자바 (61 자)

while(s!=72)for(i=0,s=0;i<18;i++)s+=3+(int)(Math.random()*3);

샘플 출력 :

5 4 3 4 5 3 4 4 3 5 4 4 4 4 3 4 4 5

Java 전문가는 아니지만 s 및 i 선언과 System # println (..)에 대한 호출이 없어야합니까?
hiergiltdiestfu

이것은 프로그램이 아닌 코드 스 니펫입니다. 그리고 실제로 @JoeIbanez 'C 버전과 매우 비슷합니다.
Franz D.

2

C (94 자)

int h[18],s=0,i;
while(s!=72)for(i=s=0;i<18;s+=h[i++]=rand()%3+3);
while(i)printf("%d ",h[--i]);

s=0라인 1은 가능성은 무엇 때문에 초기화 INT (72)와 동일 할 필요하지 않을 수? 나는 C에서 초기화되지 않은 값을 읽는 것을 좋아하지 않습니다 rand().

산출

3 3 3 4 5 5 3 3 4 5 5 4 3 4 5 5 5 3 

그래서 기본적으로 당신은 72가 될 때까지 3에서 5 사이의 18 개의 숫자로 구성된 임의의 문자열을 반복 할 것입니까? 좋은 일 효율성은 필수가 아닙니다.
KeithS

5
@KeithS 공정하게 말하면,이 질문에 대한 대부분의 답변이하고 있습니다.
Gareth

2

배쉬 쉘 스크립트 (65 자)

shuf -e `for x in {0..8}
do echo $((r=RANDOM%3+3)) $((8-r))
done`

( shuf 는 GNU coreutils 패키지에서 제공됩니다. 또한 Gareth에게 감사드립니다.)


2

C # (143 비 공백) :

()=>{
  var n=new Math.Random().Next(10);
  Enumerable.Range(1,18)
    .Select((x,i)=>i<n?3:i>=18-n?5:4)
    .OrderBy(x=>Guid.NewGuid())
    .ForEach(Console.Write);
}

new Guid()빈 GUID를 만듭니다. 고유 한 GUID를 실제로 생성하려면 정적 메소드를 호출해야합니다 Guid.NewGuid.
Rotsor

그리고 당신은 두 개의 off-by-one 에러가 있습니다. x-1 대신 상수 3을 사용하고 x + 1 대신 5를 사용하여 크기를 줄일 수 있습니다. 그런 다음 Enumerable.Repeat을 Enumerable.Range로 바꿀 수 있습니다.
Mormegil

편집; 여전히 143 자
KeithS

더있다 Math.Random, 그것은 없습니다 System.Random.
코드 InChaos

또 다른 C # 접근 방식 (143 자) :var r=new Random();for(;;){var e=Enumerable.Range(1,18).Select(i=>r.Next(3,6)).ToList();if(e.Sum()==72){e.ForEach(i=>Console.Write(i));break;}}
thepirat000


2

펄, 74

{@c=map{3+int rand 3}(0)x18;$s=0;$s+=$_ for@c;redo unless$s==72}print"@c"

대체 솔루션 :

@q=((3,5)x($a=int rand 9),(4,4)x(9-$a));%t=map{(rand,$_)}(0..17);print"@q[@t{sort keys%t}]"

2

TXR (99 자)

@(bind g@(for((x(gen t(+ 3(rand 3))))y)(t)((pop x))(set y[x 0..18])(if(= [apply + y]72)(return y))))

이 표현식은 3에서 5 사이의 무한 난수 목록을 생성합니다.

(gen t (+ 3(rand 3)))  ;; t means true: while t is true, generate.

나머지 논리는이 목록의 처음 18 개 요소가 최대 72 개인 지 추가하는 간단한 루프입니다. 그렇지 않은 경우 요소를 제거하고 다시 시도합니다. for루프라고 내재 블록을 포함 nil하고 있으므로 (return ...)루프를 종료하고 값을 리턴하기 위해 사용될 수있다.

99 자 길이에는 종료 줄 바꿈이 포함되어 있어야합니다.


나는 (t)를 ()로 대체 할 수있는 커밋을 넣었다. :)
Kaz

2

APL 12

4+{⍵,-⍵}?9⍴2

인덱스 원점을 0으로 설정했습니다. 즉, 배열은 0에서 시작합니다 ⎕IO←0.를 사용 하여 설정할 수 있습니다 .


질문은 가능한 모든 구성을 생성 할 수있는 프로그램을 묻습니다. 당신은 대칭적인 것들을 만들 수 있습니다. 예를 들어 555455555333333343을 생산할 수는 없지만 적어도 나에게는 그렇게 보입니다.
Moris Zucca

2

R, 42 바이트

a=0;while(sum(a)-72)a=sample(3:5,18,r=T);a

sample기본적으로 가능한 값 (여기서는 3 4 5) 중에서 균등하게 그립니다 . 교체 용 샘플을 r=T의미합니다 replace=TRUE.


2

CJam, 17 14 바이트

CJam은이 도전보다 새로운 것이지만 어쨌든 이것이 가장 짧은 답은 아니므로 실제로 중요하지 않습니다.

Z5]Amr*I4e]mrp

여기에서 테스트하십시오.

총 72 개를 유지하려면 각각 3이와 쌍을 이루어야합니다 5. 작동 방식은 다음과 같습니다.

Z5]            e# Push [3 5].
   Amr         e# Get a random number between 0 and 9.
      *        e# Repeat the [3 5] array that many times.
       I4e]    e# Pad the array to size 18 with 4s.
           mr  e# Shuffle the array.
             p e# Print it.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.