NxN 그리드의 행, 열 및 대각선을 1에서 N까지 채 웁니다.


26

태스크

N이 주어지면, 생성 입출력 각 행, 열 및 두 대각선에 숫자 1을 포함하고 있는지의 nxn 그리드 N(또는 0 N-1 것을 쉽게인지).

입력

입력은 양의 정수 N입니다. 그리드의 열과 행 수를 나타냅니다. 이 문제의 N경우 합리적인 크기 4 ≤ N ≤ 8또는 ( 1 ≤ N ≤ 8아래 보너스를 원할 경우) 것으로 가정 할 수 있습니다 .

산출

출력은 N× N그리드입니다. 그리드의 각 행은 하나의 번호를 포함 N, 각 컬럼은 숫자 1을 포함 N하고, 길이의 두 대각선 N(중 하나의 (0,0)(N-1,N-1)으로부터 하나 (0,N-1)(N-1, 0)만에 숫자 1을 포함)를 N. 0에서 0까지의 숫자를 사용할 수 있습니다 N−1. 각각에 대해 N가능한 많은 솔루션이 있으며 찾은 첫 번째 솔루션 만 인쇄하면됩니다. 숫자 사이에 공백을 인쇄 할 필요는 없습니다.

제약

코드에서에 대한 결과를 반복적으로 생성 할 수 있어야합니다 N >= 7. 즉, 실제로 N = 7매번 코드에서 실제로 솔루션을 실행하고 솔루션을 얻을 수 있다면 좋습니다. 절대 한계와 관련하여 코드는 코드 N = 7를 실행할 때마다 10 분 이내에 해결할 수 있어야 합니다 (예를 들어, 임의의 숫자에 의존하는 경우 최악의 경우 코드는 10 분 이내에 완료되어야 함 N = 7). .

  • 입력: 4

    하나의 가능한 출력 :

    1 2 3 4
    3 4 1 2
    4 3 2 1
    2 1 4 3
    
  • 입력: 5

    하나의 가능한 출력 :

    1 2 3 4 5
    5 3 1 2 4
    2 5 4 3 1
    4 1 2 5 3
    3 4 5 1 2
    
  • 입력: 8

    하나의 가능한 출력 :

    1 2 3 4 5 6 7 8
    2 3 1 5 4 8 6 7
    4 1 2 3 7 5 8 6
    6 4 7 8 1 2 3 5
    7 5 8 2 6 3 4 1
    5 8 4 6 2 7 1 3
    8 7 6 1 3 4 5 2
    3 6 5 7 8 1 2 4
    

채점

이것은 이므로 바이트 단위의 가장 짧은 코드가 승리하지만 한 가지 예외가 있습니다. 입력의 N = 2, 3경우 유효한 솔루션이 없습니다. 코드가 이것을 처리 할 수 ​​있고 (이 경우에는 아무것도 출력하지 않고 빈 문자열을 출력하지 않고 완료 될 때까지) 여전히 처리 N = 1(출력 1)하면 바이트 수를 20 % 할인하십시오.


1
Related 하지만 대각선 요구 사항으로 인해 이러한 그리드는 작동하지 않습니다.
xnor

나는이 도전을 좋아하지만 짝수 값에 대한 알고리즘을 알아낼 수 없습니다 N. 이 JavaScript 코드는 다음과 같은 N = 1, 5 or 7경우에 for(o="",y=N;y--;o+="\n")for(x=N;x--;)o+=(((N-y)*2+x)%N)+1
유용합니다

매우 관련이 있고 가능한 중복 : codegolf.stackexchange.com/q/47846/15599
Level River St

@steveverrill 그래도 코드 골프는 아니었다.
randomra

1
어쩌면 당신은 N = 1사건 에 대해 더 분명해야합니다 : 보너스를 목표로하는 답변 1은 빈 문자열이 아닌을 반환해야 합니다.
Lynn

답변:


3

파이썬 3 275 260 바이트 * 0.8 = 220 208 바이트

재귀 / 역 추적 접근. R재귀 함수이고 l, coLumn w이며, row K이며, 다음 항목입니다.

나는 그것을 1d 배열에 넣고 색인을 더 간단하게 만들기 위해 끝에 인쇄하기로 결정했습니다.

r=range
n=(int)(input())
def R(A,I):
 l=I%n;w=I//n
 if I==n*n:[print(A[i*n:i*n+n])for i in r(n)];exit()
 for K in r(n):
  if all([all([A[i*n+l]!=K,w!=l or A[i+n*i]!=K,w!=n-1-l or A[n*i+n-i-1]!=K])for i in r(w)]+[A[w*n+i]!=K for i in r(l)]):R(A+[K],I+1)
R([],0)

언 골프 버전 :

def Recurse(A,I,n):
 column=I%n
 row=I//n
 if I==n*n:
     [print(*A[i*n:i*n+n])for i in range(n)] # output
     exit() #end recursion
 for K in range(n):
    # try every possibility. Test if they satisfy the constraints:
    # if so, move the index on. If none of them do, we'll return None.
    # if a child returns None, we'll move onto the next potential child:
    # if all of them fail it will backtrack to the next level.
    if all([
        all([
            A[i*n+column]!=K, # column constraint
            row!=column or A[i+n*i]!=K, # diagonal constraint
            row!=n-1-column or A[n*i+n-i-1]!=K # antidiagonal constraint
            ]) for i in range(row)
        ]+[
            A[row*n+i]!=K for i in range(column) # row constraint
            ]):
        Recurse(A+[K],I+1,n)

Recurse([],0,(int)(input()))

22

비 경쟁적 인 Funciton

최신 정보! 대규모 성능 향상! n = 7은 이제 10 분 안에 완료됩니다! 하단의 설명을 참조하십시오!

이것은 쓰기에 좋은 재미였습니다. 이것은 Funciton으로 작성된이 문제에 대한 무차별 대입 솔버입니다. 일부 사실 :

  • STDIN에서 정수를 허용합니다. 정수 다음의 줄 바꿈을 포함하여 불필요한 공백이 있으면 공백이 끊어집니다.
  • 0에서 n -1 사이 의 숫자를 사용합니다 (1에서 n은 아님).
  • 그리드를 "뒤로"채우므로 3 2 1 0맨 위 행이 아닌 맨 아래 행이 읽는 솔루션을 얻 습니다 0 1 2 3.
  • n = 1에 0대해 올바르게 출력합니다 (유일한 솔루션) .
  • n = 2 및 n = 3에 대한 빈 출력 .
  • exe로 컴파일 할 때 n = 7 (성능 개선 전 약 1 시간 전)에 약 8 분이 걸립니다 . (인터프리터를 사용하여) 컴파일하지 않으면 약 1.5 배의 시간이 걸리므로 컴파일러를 사용하는 것이 좋습니다.
  • 개인적인 이정표로서, 의사 코드 언어로 프로그램을 작성하지 않고 전체 Funciton 프로그램을 작성한 것은 이번이 처음입니다. 그래도 실제 C #으로 작성했습니다.
  • (그러나 이것이 Funciton에서 무언가의 성능을 크게 향상시키기 위해 처음으로 변경 한 것은 아닙니다. 처음으로 팩토리얼 기능을 사용했습니다. 곱셈의 피연산자 순서를 바꾸는 것은 큰 차이를 가져 왔습니다 곱셈 알고리즘의 작동 방식 궁금한 경우를 대비하여.)

더 이상 고민하지 않고 :

            ┌────────────────────────────────────┐           ┌─────────────────┐
            │                                  ┌─┴─╖ ╓───╖ ┌─┴─╖   ┌──────┐    │
            │                    ┌─────────────┤ · ╟─╢ Ӂ ╟─┤ · ╟───┤      │    │
            │                    │             ╘═╤═╝ ╙─┬─╜ ╘═╤═╝ ┌─┴─╖    │    │
            │                    │               └─────┴─────┘   │ ♯ ║    │    │
            │                  ┌─┴─╖                             ╘═╤═╝    │    │
            │     ┌────────────┤ · ╟───────────────────────────────┴───┐  │    │
          ┌─┴─╖ ┌─┴─╖   ┌────╖ ╘═╤═╝ ┌──────────┐         ┌────────┐ ┌─┴─╖│    │
          │ ♭ ║ │ × ╟───┤ >> ╟───┴───┘        ┌─┴─╖       │ ┌────╖ └─┤ · ╟┴┐   │
          ╘═╤═╝ ╘═╤═╝   ╘══╤═╝          ┌─────┤ · ╟───────┴─┤ << ╟─┐ ╘═╤═╝ │   │
    ┌───────┴─────┘ ┌────╖ │            │     ╘═╤═╝         ╘══╤═╝ │   │   │   │
    │     ┌─────────┤ >> ╟─┘            │       └───────┐      │   │   │   │   │
    │     │         ╘══╤═╝            ┌─┴─╖   ╔═══╗   ┌─┴─╖ ┌┐ │   │ ┌─┴─╖ │   │
    │     │           ┌┴┐     ┌───────┤ ♫ ║ ┌─╢ 0 ║ ┌─┤ · ╟─┤├─┤   ├─┤ Ӝ ║ │   │
    │     │   ╔═══╗   └┬┘     │       ╘═╤═╝ │ ╚═╤═╝ │ ╘═╤═╝ └┘ │   │ ╘═╤═╝ │   │
    │     │   ║ 1 ╟───┬┘    ┌─┴─╖       └───┘ ┌─┴─╖ │   │      │   │   │ ┌─┴─╖ │
    │     │   ╚═══╝ ┌─┴─╖   │ ɓ ╟─────────────┤ ? ╟─┘   │    ┌─┴─╖ │   ├─┤ · ╟─┴─┐
    │     ├─────────┤ · ╟─┐ ╘═╤═╝             ╘═╤═╝   ┌─┴────┤ + ╟─┘   │ ╘═╤═╝   │
  ┌─┴─╖ ┌─┴─╖       ╘═╤═╝ │ ╔═╧═╕ ╔═══╗ ┌───╖ ┌─┴─╖ ┌─┴─╖    ╘═══╝     │   │     │
┌─┤ · ╟─┤ · ╟───┐     └┐  └─╢   ├─╢ 0 ╟─┤ ⌑ ╟─┤ ? ╟─┤ · ╟──────────────┘   │     │
│ ╘═╤═╝ ╘═╤═╝   └───┐ ┌┴┐   ╚═╤═╛ ╚═╤═╝ ╘═══╝ ╘═╤═╝ ╘═╤═╝                  │     │
│   │   ┌─┴─╖ ┌───╖ │ └┬┘   ┌─┴─╖ ┌─┘           │     │                    │     │
│ ┌─┴───┤ · ╟─┤ Җ ╟─┘  └────┤ ? ╟─┴─┐   ┌─────────────┘                    │     │
│ │     ╘═╤═╝ ╘═╤═╝         ╘═╤═╝   │   │╔════╗╔════╗                      │     │
│ │       │  ┌──┴─╖ ┌┐   ┌┐ ┌─┴─╖ ┌─┴─╖ │║ 10 ║║ 32 ║    ┌─────────────────┘     │
│ │       │  │ << ╟─┤├─┬─┤├─┤ · ╟─┤ · ╟─┘╚══╤═╝╚╤═══╝ ┌──┴──┐                    │
│ │       │  ╘══╤═╝ └┘ │ └┘ ╘═╤═╝ ╘═╤═╝     │ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖                  │
│ │     ┌─┴─╖ ┌─┴─╖  ┌─┴─╖  ┌─┴─╖ ╔═╧═╕     └─┤ ? ╟─┤ · ╟─┤ % ║                  │
│ └─────┤ · ╟─┤ · ╟──┤ Ӂ ╟──┤ ɱ ╟─╢   ├───┐   ╘═╤═╝ ╘═╤═╝ ╘═╤═╝                  │
│       ╘═╤═╝ ╘═╤═╝  ╘═╤═╝  ╘═══╝ ╚═╤═╛ ┌─┴─╖ ┌─┴─╖   │     └────────────────────┘
│         └─────┤      │            └───┤ ‼ ╟─┤ ‼ ║   │        ┌──────┐
│               │      │                ╘═══╝ ╘═╤═╝   │        │ ┌────┴────╖
│               │      │                      ┌─┴─╖   │        │ │ str→int ║
│               │      └──────────────────────┤ · ╟───┴─┐      │ ╘════╤════╝
│               │          ┌─────────╖        ╘═╤═╝     │    ╔═╧═╗ ┌──┴──┐
│               └──────────┤ int→str ╟──────────┘       │    ║   ║ │ ┌───┴───┐
│                          ╘═════════╝                  │    ╚═══╝ │ │ ┌───╖ │
└───────────────────────────────────────────────────────┘          │ └─┤ × ╟─┘
           ┌──────────────┐                                  ╔═══╗ │   ╘═╤═╝
╔════╗     │ ╓───╖ ┌───╖  │                              ┌───╢ 0 ║ │   ┌─┴─╖ ╔═══╗
║ −1 ║     └─╢ Ӝ ╟─┤ × ╟──┴──────┐                       │   ╚═╤═╝ └───┤ Ӂ ╟─╢ 0 ║
╚═╤══╝       ╙───╜ ╘═╤═╝         │                       │   ┌─┴─╖     ╘═╤═╝ ╚═══╝
┌─┴──╖ ┌┐ ┌───╖ ┌┐ ┌─┴──╖ ╔════╗ │                       │ ┌─┤   ╟───────┴───────┐
│ << ╟─┤├─┤ ÷ ╟─┤├─┤ << ║ ║ −1 ║ │                       │ │ └─┬─╜ ┌─┐ ┌─────┐   │
╘═╤══╝ └┘ ╘═╤═╝ └┘ ╘═╤══╝ ╚═╤══╝ │                       │ │   └───┴─┘ │   ┌─┴─╖ │
  │         └─┘      └──────┘    │                       │ └───────────┘ ┌─┤ ? ╟─┘
  └──────────────────────────────┘         ╓───╖         └───────────────┘ ╘═╤═╝
                               ┌───────────╢ Җ ╟────────────┐                │
      ┌────────────────────────┴───┐       ╙───╜            │
      │                          ┌─┴────────────────────┐ ┌─┴─╖
    ┌─┴─╖                      ┌─┴─╖                  ┌─┴─┤ · ╟──────────────────┐
    │ ♯ ║ ┌────────────────────┤ · ╟───────┐          │   ╘═╤═╝                  │
    ╘═╤═╝ │                    ╘═╤═╝       │          │     │              ┌───╖ │
┌─────┴───┘    ┌─────────────────┴─┐   ┌───┴───┐    ┌─┴─╖ ┌─┴─╖          ┌─┤ × ╟─┴─┐
│              │                 ┌─┴─╖ │   ┌───┴────┤ · ╟─┤ · ╟──────────┤ ╘═╤═╝   │
│              │ ┌───╖ ┌───╖  ┌──┤ · ╟─┘ ┌─┴─┐      ╘═╤═╝ ╘═╤═╝        ┌─┴─╖ │     │
│         ┌────┴─┤ ♭ ╟─┤ × ╟──┘  ╘═╤═╝   │ ┌─┴─╖ ┌───╖└┐ ┌──┴─╖      ┌─┤ · ╟─┘     │
│         │      ╘═══╝ ╘═╤═╝ ┌───╖ │     │ │ × ╟─┤ Ӝ ╟─┴─┤ ÷% ╟─┐    │ ╘═╤═╝ ┌───╖ │
│   ┌─────┴───┐     ┌────┴───┤ Ӝ ╟─┴─┐   │ ╘═╤═╝ ╘═╤═╝   ╘══╤═╝ │    │   └───┤ Ӝ ╟─┘
│ ┌─┴─╖ ┌───╖ │     │ ┌────╖ ╘═╤═╝   │   └───┘   ┌─┴─╖      │   │    └────┐  ╘═╤═╝
│ │ × ╟─┤ Ӝ ╟─┘     └─┤ << ╟───┘   ┌─┴─╖ ┌───────┤ · ╟───┐  │ ┌─┴─╖ ┌───╖ │    │
│ ╘═╤═╝ ╘═╤═╝         ╘══╤═╝   ┌───┤ + ║ │       ╘═╤═╝   ├──┴─┤ · ╟─┤ × ╟─┘    │
└───┤     └────┐ ╔═══╗ ┌─┴─╖ ┌─┴─╖ ╘═╤═╝ │ ╔═══╗ ┌─┴─╖ ┌─┴─╖  ╘═╤═╝ ╘═╤═╝      │
  ┌─┴─╖ ┌────╖ │ ║ 0 ╟─┤ ? ╟─┤ = ║  ┌┴┐  │ ║ 0 ╟─┤ ? ╟─┤ = ║    │     │ ┌────╖ │
  │ × ╟─┤ << ╟─┘ ╚═══╝ ╘═╤═╝ ╘═╤═╝  └┬┘  │ ╚═══╝ ╘═╤═╝ ╘═╤═╝    │     └─┤ << ╟─┘
  ╘═╤═╝ ╘═╤══╝ ┌┐     ┌┐ │     │     └───┘       ┌─┴─╖   ├──────┘       ╘═╤══╝
    │     └────┤├──┬──┤├─┘     ├─────────────────┤ · ╟───┘                │
    │          └┘┌─┴─╖└┘       │     ┌┐   ┌┐     ╘═╤═╝ ┌┐   ┌┐            │
    └────────────┤ · ╟─────────┘   ┌─┤├─┬─┤├─┐     └───┤├─┬─┤├────────────┘
                 ╘═╤═╝             │ └┘ │ └┘ │         └┘ │ └┘
                   └───────────────┘    │    └────────────┘

첫 번째 버전의 설명

첫 번째 버전은 n = 7 을 해결하는 데 약 1 시간이 걸렸습니다 . 다음은이 느린 버전의 작동 방식을 설명합니다. 하단에는 10 분 미만으로 변경 한 내용이 설명되어 있습니다.

비트 여행

이 프로그램에는 비트가 필요합니다. 많은 비트가 필요하며 모든 올바른 위치에 비트가 필요합니다. 숙련 된 Funciton 프로그래머는 이미 n 비트 가 필요한 경우 공식을 사용할 수 있음을 알고 있습니다.

2 ^ n-1

Funciton에서 다음과 같이 표현 될 수 있습니다.

(1 << n)-1

성능 최적화를 수행 할 때이 공식을 사용하여 동일한 값을 훨씬 빠르게 계산할 수있었습니다.

¬ (−1 << n)

나는이 게시물의 모든 방정식 그래픽을 그에 따라 업데이트하지 않았다는 것을 용서하기를 바랍니다.

이제 연속적인 비트 블록을 원하지 않는다고 가정 해 봅시다. 실제로 k 번째 비트 마다 일정한 간격으로 n 비트 를 원합니다 .

                                 LSB
                                  ↓
00000010000001000000100000010000001
                            └──┬──┘
                               k

이것에 대한 공식은 일단 알면 매우 간단합니다.

((1 << nk)-1) / ((1 << k)-1)

코드에서 함수 Ӝ는 값 nk를 가져 와서이 공식을 계산합니다.

사용 된 숫자 추적

최종 그리드 에는 n ² 개의 숫자가 있으며 각 숫자는 n 개의 가능한 값 중 하나 일 수 있습니다. 각 셀에서 어떤 숫자가 허용되는지 추적하기 위해, 우리는 n ³ 비트로 구성된 숫자를 유지하는데 , 여기서 특정 값이 취해 졌음을 나타내는 비트가 설정됩니다. 처음에는이 숫자가 0입니다.

알고리즘은 오른쪽 하단에서 시작합니다. 첫 번째 숫자를 "추측"한 후에는 동일한 행, 열 및 대각선을 따라 어떤 셀에서도 0이 더 이상 허용되지 않는다는 사실을 추적해야합니다.

LSB                               (example n=5)
 ↓
 10000 00000 00000 00000 10000
 00000 10000 00000 00000 10000
 00000 00000 10000 00000 10000
 00000 00000 00000 10000 10000
 10000 10000 10000 10000 10000
                             ↑
                            MSB

이를 위해 다음 네 가지 값을 계산합니다.

  • 현재 행 : 우리는 n 번째 비트마다 n 비트 가 필요 하며 (셀당 1 개), 모든 행에 n ² 비트 가 포함되어 있음을 기억 하여 현재 행 r 로 이동합니다 .

    ((1 << n²) −1) / ((1 << n) −1) << n²r

  • 현재 열 : 우리는 n ² 번째 비트마다 n 비트 가 필요 하며 (행 당 하나씩) 모든 열에 n 비트 가 포함되어 있음을 기억 하여 현재 열 c 로 이동하십시오 .

    ((1 << n³) −1) / ((1 << n²) −1) << n²r

  • 앞으로 대각선 : 우리는 필요가 N 모든 비트 ... (?! 당신이 관심 빠른, 그림을 지불 않았다) N ( n은 우리가 실제로 +1) 번째 비트 (! 잘 했어), 그러나있어 경우에만 전방 대각선 :

    c = r 인 경우 ((1 << n² (n + 1)) − 1) / ((1 << n (n + 1)) − 1)

  • 뒤로 대각선 : 여기 두 가지. 첫째, 우리가 후방 대각선에 있는지 어떻게 알 수 있습니까? 수학적으로 조건은 c = ( n -1) -r 이며 c = n + (− r -1)와 같습니다. 이봐, 뭔가 생각나? 맞습니다, 그것은 2의 보수이므로, 우리는 감소 대신 비트 단위 부정 (Funciton에서 매우 효율적)을 사용할 수 있습니다. 둘째, 위의 공식은 우리가 최하위 비트가 세트가되고 싶어한다고 가정하지만, 우리는 당신이 알고에 의해 ... 그것을 이동해야하므로 역방향 대각선에서 우리가하지? ... 그건 바로, N ( n -1).

    c = n + ¬ 인 경우 ((1 << n² (n-1)) − 1) / ((1 << n (n-1))-1) << n (n-1)

    이것은 또한 n = 1 인 경우 잠재적으로 0으로 나눌 수있는 유일한 것입니다 . 그러나 Funciton은 상관하지 않습니다. 0 ÷ 0은 0에 불과합니다.

코드에서 함수 Җ(하단)는 n인덱스 ( 분할 및 나머지로 rc 를 계산 하는 인덱스 )를 가져 와서이 4 개의 값을 계산 or하고 함께 s합니다.

무차별 알고리즘

무차별 알고리즘은 Ӂ(상단의 기능)에 의해 구현됩니다 . 그것은 소요 N (격자 크기), 인덱스 (그리드에 우리가 현재 숫자를 배치하고), 및 촬영 (와 수를 n은 우리에게 어떤 숫자를 말하는 ³ 비트 우리가 할 수있는 각 셀에서 여전히 위).

이 함수는 일련의 문자열을 반환합니다. 각 문자열은 그리드에 대한 완전한 솔루션입니다. 완전한 솔버입니다. 허용하면 모든 솔루션을 반환하지만 지연 평가 시퀀스로 반환합니다.

  • 경우 지수가 0에 도달 한 우리는 빈 문자열을 포함하는 순서 (단일 솔루션을 그 세포의 표지 없음) 반환 그래서, 우리는 성공적으로 전체 그리드를 작성했습니다. 빈 문자열은입니다 0. 라이브러리 함수 를 사용하여 단일 요소 시퀀스로 바꿉니다.

  • 아래 성능 개선에 설명 된 점검이 여기에서 발생합니다.

  • 인덱스 가 아직 0에 도달하지 않은 경우 숫자를 배치해야하는 인덱스를 얻기 위해 인덱스를 1 씩 줄입니다 ( ix 호출 ).

    0에서 n -1 사이의 값을 포함하는 지연 시퀀스를 생성하는 데 사용 합니다 .

    그런 ɓ다음 순서대로 다음을 수행하는 람다와 함께 (모 노드 바인드)를 사용합니다.

    • 의 관련 비트에서 먼저 살펴 찍은 번호가 여기 여부 유효한지 여부를 결정합니다. 우리는 다수 배치 할 수 있습니다 경우에만 촬영 & (1 << ( N × IX ) << 내가 ) 아직 설정되지 않습니다. 설정된 경우 0(빈 시퀀스)를 반환 합니다.
    • Җ현재 행, 열 및 대각선에 해당하는 비트를 계산하는 데 사용 합니다. 하여 시프트 다음 or그것을로 촬영 .
    • 재귀 호출 Ӂ그것을 새로운 전달, 나머지 셀에 대한 모든 솔루션을 검색하기 위해 촬영 과 감소 IX를 . 불완전한 문자열 시퀀스를 반환합니다. 각 문자열에는 ix 개의 문자가 있습니다 (그리드는 인덱스 ix 까지 채워짐 ).
    • 사용 ɱ(지도) thusly 히있는 솔루션을 통해 이동 및 사용에 연결하는 난을 각각의 끝에. indexn 의 배수 이면 개행을 추가하고 , 그렇지 않으면 공백을 추가하십시오.

결과 생성

주요 프로그램 호출 Ӂ과 (짐승의 강제 자) N , 인덱스 = N ²가와 (우리는 그리드 뒤쪽을 채우기 기억) 촬영 = 0 (처음에 아무것도 수행되지 않습니다). 이 결과가 빈 시퀀스 인 경우 (솔루션이 없음) 빈 문자열을 출력하십시오. 그렇지 않으면 순서에서 첫 번째 문자열을 출력하십시오. 이는 시퀀스의 첫 번째 요소 만 평가한다는 것을 의미하므로 솔버가 모든 솔루션을 찾을 때까지 계속되지 않습니다.

성능 향상

(이전 버전의 설명을 이미 읽은 사람들을 위해 : 프로그램은 더 이상 출력을 위해 문자열로 개별적으로 전환해야하는 시퀀스 시퀀스를 더 이상 생성하지 않고 단지 문자열 시퀀스를 직접 생성합니다. 그러나 이것이 주요 개선 사항은 아니 었습니다.

내 컴퓨터에서 첫 번째 버전의 컴파일 된 exe는 n = 7 을 해결하는 데 거의 정확히 1 시간이 걸렸습니다 . 이는 주어진 시간 제한 10 분이 아니므로 쉬지 않았습니다. (실제로, 내가 휴식을 취하지 않은 이유는 그것이 어떻게 속도를 높이는 지에 대한 아이디어를 가지고 있었기 때문입니다.)

위에서 설명한 알고리즘은 취한 숫자 의 모든 비트 가 설정된 셀을 발견 할 때마다 검색을 중지하고 역 추적하므로이 셀에 아무것도 넣을 수 없음을 나타냅니다.

그러나 알고리즘은 그리드 를 모든 비트가 설정된 셀 까지 계속 쓸데없이 채 웁니다 . 아직 채워 지지 않은 셀에 이미 모든 비트가 설정 되어 있으면 중지 할 수 있다면 훨씬 빠를 것 입니다. 이는 이미 어떤 숫자를 입력하더라도 그리드의 나머지 부분을 해결할 수 없음을 나타냅니다. 그것. 그러나 모든 셀을 거치지 않고 셀에 n 비트가 설정 되어 있는지 어떻게 효율적으로 확인 합니까?

트릭은 셀당 단일 비트를 취한 숫자 에 추가하여 시작합니다 . 위에 표시된 것 대신 이제 다음과 같습니다.

LSB                               (example n=5)
 ↓
 10000 0 00000 0 00000 0 00000 0 10000 0
 00000 0 10000 0 00000 0 00000 0 10000 0
 00000 0 00000 0 10000 0 00000 0 10000 0
 00000 0 00000 0 00000 0 10000 0 10000 0
 10000 0 10000 0 10000 0 10000 0 10000 0
                                       ↑
                                      MSB

n ³ 대신 이 숫자에 n ² ( n + 1) 비트가 있습니다. 현재 행 / 열 / 대각선을 채우는 기능이 그에 따라 변경되었습니다 (실제로 완전히 정직하도록 다시 작성). 이 함수는 여전히 셀당 n 비트 만 채우 므로 방금 추가 한 추가 비트는 항상입니다 0.

이제 우리는 계산 1의 중간 단계 에 있고 중간 셀에 방금 배치 했으며 촬영 한 숫자는 다음과 같습니다.

                 current
LSB              column           (example n=5)
 ↓                 ↓
 11111 0 10010 0 01101 0 11100 0 11101 0
 00011 0 11110 0 01101 0 11101 0 11100 0
 11111 0 11110 0[11101 0]11100 0 11100 0    ← current row
 11111 0 11111 0 11111 0 11111 0 11111 0
 11111 0 11111 0 11111 0 11111 0 11111 0
                                       ↑
                                      MSB

보다시피 왼쪽 상단 셀 (인덱스 0)과 왼쪽 중앙 셀 (인덱스 10)은 불가능합니다. 우리는 이것을 어떻게 가장 효율적으로 결정합니까?

각 셀의 0 번째 비트가 설정되었지만 현재 인덱스까지만 설정된 숫자를 고려하십시오. 이러한 수는 익숙한 공식을 사용하여 쉽게 계산할 수 있습니다.

((1 << (n + 1) i)-1) / ((1 << (n + 1))-1)

이 두 숫자를 더하면 어떻게 되나요?

LSB                                               LSB
 ↓                                                 ↓
 11111 0 10010 0 01101 0 11100 0 11101 0           10000 0 10000 0 10000 0 10000 0 10000 0        ╓───╖
 00011 0 11110 0 01101 0 11101 0 11100 0     ║     10000 0 10000 0 10000 0 10000 0 10000 0            ║
 11111 0 11110 0 11101 0 11100 0 11100 0  ═══╬═══  10000 0 10000 0 00000 0 00000 0 00000 0  ═════   ╓─╜
 11111 0 11111 0 11111 0 11111 0 11111 0     ║     00000 0 00000 0 00000 0 00000 0 00000 0  ═════   ╨
 11111 0 11111 0 11111 0 11111 0 11111 0           00000 0 00000 0 00000 0 00000 0 00000 0          o
                                       ↑                                                 ↑
                                      MSB                                               MSB

결과는 다음과 같습니다.

             OMG
              ↓
        00000[1]01010 0 11101 0 00010 0 00011 0
        10011 0 00001 0 11101 0 00011 0 00010 0
═════   00000[1]00001 0 00011 0 11100 0 11100 0
═════   11111 0 11111 0 11111 0 11111 0 11111 0
        11111 0 11111 0 11111 0 11111 0 11111 0

보시다시피, 추가는 추가 한 여분의 비트로 넘치지 만 해당 셀의 모든 비트가 설정된 경우에만 추가됩니다! 따라서 남은 것은 비트를 마스킹하고 (위와 같은 식이지만 << n ) 결과가 0인지 확인하는 것입니다.

00000[1]01010 0 11101 0 00010 0 00011 0    ╓╖    00000 1 00000 1 00000 1 00000 1 00000 1         ╓─╖ ╓───╖
10011 0 00001 0 11101 0 00011 0 00010 0   ╓╜╙╖   00000 1 00000 1 00000 1 00000 1 00000 1        ╓╜ ╙╖    ║
00000[1]00001 0 00011 0 11100 0 11100 0   ╙╥╥╜   00000 1 00000 1 00000 0 00000 0 00000 0  ═════ ║   ║  ╓─╜
11111 0 11111 0 11111 0 11111 0 11111 0   ╓╜╙╥╜  00000 0 00000 0 00000 0 00000 0 00000 0  ═════ ╙╖ ╓╜  ╨
11111 0 11111 0 11111 0 11111 0 11111 0   ╙──╨─  00000 0 00000 0 00000 0 00000 0 00000 0         ╙─╜   o

그것이 0이 아니면 그리드는 불가능하며 우리는 멈출 수 있습니다.

  • n = 4 ~ 7의솔루션 및 실행 시간을 보여주는 스크린 샷

3
거시기. 야, 그거 인상적이야.
Deusovi

1
내가 두 번째 Deusovi의 코멘트 @,이에 너무 많은 노력을 넣어 주셔서 감사합니다
hargasinski

7

하스켈, 790 * 0.80 = 632 바이트

import Data.List
import Control.Monad
import Data.Array
s r=let{h as bs=[(a,b)|a<-as,b<-bs];(&)m k=(\(Just x)->x)$lookup k m;j=Just;n=Nothing;c=[1..r];q=delete;u=h[1..r]c;o=[(s,[u |u<-[h[1..r][c]|c<-c]++[h[r]c|r<-[1..r]]++[zip[1..r][1..r],zip[1..r][r,r-1..1]],s`elem`u])|s<-u];k=foldr(>=>)j;a p d g0=k[t p d2|d2<-q d(g0!p)]g0;t p d g0|not(d`elem`(g0!p))=j g0|[]<-v=n|[d2]<-v=k[t s2 d2|s2<-[(s,delete s$nub(concat(o&s)))|s<-u]&p]g1|True=k[l[s|s<-u,not(d`elem`v)]|u<-o&p]g1 where{v=q d(g0!p);g1=g0//[(p,v)];l[]_=n;l[d3]g=a d3 d g;l _ r=j r};w g0|and[case g0!s of{[_]->True;_->False}|s<-u]=j g0|True=msum[a s' d g0>>=w|d<-g0!s']where(_,s')=minimumBy(\(a,_)(b,_)->compare a b)[(l,s)|s<-u,let v=g0!s;l=length v,l>1]}in fmap(fmap(\[x]->x))$w$array((1,1),(r,r))[((i,j),[1..r])|i<-[1..r],j<-[1..r]]

이 문제는 스도쿠와 매우 유사하다는 것을 알았습니다. 필자는 Haskell 에서 파이썬에서 작성한 다른 스도쿠 솔버를 기억합니다 . 이것은 나의 첫 번째 코드 골프 포스트 또는 시도입니다.

그것을 반환하기 때문에이 보너스를 충족 Nothing하기위한 n=2,3Just <result>에 대한 n>=4경우, <result>정수 값의 2 차원 배열입니다.

온라인 통역사를 보려면 여기 를 참조 하십시오 . 온라인 통역사가 완전한 프로그램을 구성하는 양식에 대해 더 엄격한 요구 사항이 있기 때문에 해당 코드는 실제로 게시물의 코드보다 깁니다 (규칙은 제출이 함수일 수 있음). 이 제출은 함수 인수로 입력을받습니다.


1
몇 가지 간단한 팁 : a)을 정의 c=[1..r]하여 o및 에서 사용할 수 있습니다 w. b) minimumBy(\(a,_)(b,_)->compare a b)[...]head$sortOn fst[...]입니다. c) vin v=g0!s은 한 번만 사용되므로 전혀 정의하지 마십시오 l=length$g0!s. d) 여전히 두 글자 문자 이름이 있습니다. 전자) 교체 True와 함께 1<2False함께 2<1. f) and[case g0!s of{[_]->True;_->False}|s<-u]all((==1).length.(g0!))u입니다.
nimi

빠른 팁, 파트 II : g) (&)m k=접두사를 정의 할 수 있습니다 m&k=. h) not(delem (g0!p))notElem d$g0!p입니다. i) concat(...)id=<<(...)입니다. j) h예를 들어 as%bs=.
nimi

3
빠른 메타 팁 : 이중 백틱을 사용하여 백틱이있는 코드를 올바르게 구분할 수 있습니다 ​``like`this``​!
Lynn

4

Pyth, 41 바이트

#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K
#                                      ;   # while(True)
 Km.SQQ                                    # K = random QxQ 2d list
       I                               ;   # if ...
        .A                                 # all of...
          m                          Q     # map(range(Q))...
                +                          # concat
                 .TK                       # transpose K
                    .Tm,@@Kdd@@Kt-Qdd      # diagonals of K
                      m             d      # map(range(d))
                       ,                   # 2-elem list of...
                        @@Kdd              # K[n][n]
                             @@Kt-Qd       # and K[len(K)-n-1][n]
                    .T                     # transpose
           qQl{d                           # subarrays have no dups...
                                      B;   # ... then, break
                                        K  # output final result

무차별 대입!

이것은 기본적으로 작동 할 때까지 무작위 셔플을 계속 시도하기 때문에 (잘 계속 시도합니다 n * [shuffle(range(n))]) 실제로 시간이 오래 걸립니다. 소요 시간에 대한 아이디어를 제공하는 몇 가지 테스트 실행은 다음과 같습니다.

llama@llama:~$ time echo 4 | pyth <(echo '#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K')               
[[2, 1, 0, 3], [0, 3, 2, 1], [3, 0, 1, 2], [1, 2, 3, 0]]
echo 4  0.00s user 0.00s system 0% cpu 0.001 total
pyth <(echo '#Km.SQQI.AmqQl{d+.TK.Tm,@@Kdd@@Kt-QddQB;K')  0.38s user 0.00s system 96% cpu 0.397 total

이는 4x4에 불과하며 0.5 초도 채 걸리지 않습니다. 나는 이것이 몇 번의 시험 중 최고이기 때문에 실제로 속임수를 쓰고 있습니다. 대부분은 1-2 초가 걸립니다.

아직 5x5의 타이밍을 얻지 못했습니다 (한 번 완료되었지만 REPL에 있었고 타이밍이 아니 었습니다).

시간 제한 규칙은이 답변이 게시 된 후에 만 ​​질문으로 편집되었습니다.


나는 이것이 10 분 안에 7x7을 할 수 없다고 생각합니까? ^^
Lynn

@Mauris 글쎄, 때로는 할 수 ... ...) 내가 놓친 요구 사항입니까? 질문에 시간 제한을 언급하는 내용이 없습니다.
Doorknob

나는 코멘트에서 그것을 본다 ( 12 시간 전 새로운 코멘트가 아님 )
edc65

그것에 대해 죄송합니다, 누군가 그것을 언급하기 전까지는 생각하지 못했습니다, 지금 도전을 편집하겠습니다
hargasinski

1
주석이 달린 버전의 추상 ASCII 아트는 +1입니다. :)
Ilmari Karonen

3

SWI- 프롤로그, 326 * 0.80 = 260.8 바이트

:-use_module(library(clpfd)).
a(N):-l(N,R),m(l(N),R),append(R,V),V ins 1..N,transpose(R,C),d(0,R,D),maplist(reverse,R,S),d(0,S,E),m(m(all_distinct),[R,C,[D,E]]),m(label,R),m(p,R).
l(L,M):-length(M,L).
d(X,[H|R],[A|Z]):-nth0(X,H,A),Y is X+1,(R=[],Z=R;d(Y,R,Z)).
p([H|T]):-write(H),T=[],nl;write(' '),p(T).
m(A,B):-maplist(A,B).

편집 : @Mat 덕분에 16 바이트 저장

용법

a(5).통역사에게 전화 하십시오 N=5. 이것은 반환 false을 위해 N=2N=3.

CLPFD 라이브러리를 사용하기 때문에 순수한 무차별 대입은 아닙니다. 이 프로그램은 N=20내 컴퓨터에서 약 15 초 동안 해결책을 찾을 수 있습니다.

언 골프 + 설명 :

이것은 기본적으로 블록 제약 조건이 대각선 제약 조건으로 대체된다는 점을 제외하고는 스도쿠 솔버처럼 작동합니다.

:-use_module(library(clpfd)).      % Import Constraints library

a(N):-
    l(N,R),                        % R is a list of length N
    maplist(l(N),R),               % R contains sublists, each of length N
    append(R,V),                   
    V ins 1..N,                    % Each value in the matrix is between 1 and N
    maplist(all_distinct,R),       % Values must be different on each row
    transpose(R,C),
    maplist(all_distinct,C),       % Values must be different on each column
    d(0,R,D),
    maplist(reverse,R,S),          
    d(0,S,E),
    all_distinct(D),               % Values must be different on the diagonal
    all_distinct(E),               % Values must be different on the "anti"-diagonal
    maplist(label,R),              % Affects actual values to each element
    maplist(p,R).                  % Prints each row

l(L,M):-length(M,L).               % True if L is the length of M

d(X,[H|R],[A|Z]):-nth0(X,H,A),Y is X+1,(R=[],Z=R;d(Y,R,Z)). % True if the third argument is the diagonal of the second argument

p([H|T]):-write(H),T=[],nl;write(' '),p(T).  % Prints a row separated by spaces and followed by a new line

아주 좋아요! 다음을 사용하여 바이트를 저장할 수 있습니다.maplist(maplist(all_distinct), [R,C,D,E])
mat

1
@mat 제안 해 주셔서 감사합니다. 16 바이트를 절약합니다. 내가 사용할 필요가 [R,C,[D,E]]있기 때문에, 비록 ED간단한 목록입니다.
Fatalize

맞아요, 아주 좋은 해결 방법!
mat

2
@Fatalize 알려 드리기 만하면 솔루션이 유일하게 해결 N=20
되었으므로

1
@Zequ 감사합니다! 그러나 이것은 주로 다음과 같은 문제에서 많은 노력을 기울이고있는 놀라운 Prolog CLPFD 라이브러리 때문입니다.)
Fatalize

2

CJam, 87 바이트-20 % 보너스 = 69.6 바이트

qi__"@I/l
ŤˏūȻ
܀ᅀ൹৽჈͚
㑢鴑慚菥洠㬝᚜
"N/=:i0+\,m!f=`1LL](4e<=

답변을 하드 코드합니다. 인쇄 할 수없는 것들이 포함되어 있습니다. N = 1통해 작동합니다 N = 8.

기본적으로이 신비한 문자열의 각 줄에는 순열 목록에 대한 색인이 포함되어 range(N)있으며 유니 코드 문자로 인코딩됩니다.

=:i0+\,m!f=맨 아래 행을 나타내는 인덱스 목록의 끝에 0을 추가하여 순열 목록에 인덱스합니다 0 1 2 ... N-1. 의 경우 N < 4결과 2D 배열은 의미가 없습니다.

`1LL]목록을 만듭니다 [N, pretty output, 1, "", ""]. 그런 다음 (4e<=이 목록에서 첫 번째 요소를 팝 하고 나머지 요소에서 th 요소를 N검색 min(N, 4) % 4합니다. 들면 N >= 4, 그 출력이고, 그렇지 않으면 처음 세 경우에 특별한 경우의 출력이다.

여기에서 시도하십시오 .


0

C ++, 672 * 0.80 645 * 0.80 = 516 바이트

#include <iostream>
int **b,**x,**y,*d,*a,n;
#define R(i) for(i=0;i<n;i++){
#define E(e) e=new int[n];
int f(int c,int r) {int i=0,p=c-1;if(r>=n)return 1;if(c == n + 1)return f(1,r+1);R(i)int m=r==i,s=r+i==n-1;if(!b[r][i]&&!x[r][p]&&!(m&&d[p])&&!(s&&a[p])&&!y[i][p]){b[r][i]=c;x[r][p]=1;y[i][p]=1;if(m)d[p]=1;if(s)a[p]=1;if(f(c+1,r))return 1;b[r][i]=0;x[r][p]=0;y[i][p]=0;if(m)d[p]=0;if(s)a[p]=0;}}return 0;}
int main(){std::cin>>n;int i=0,j=0;b=new int*[n];x=new int*[n];y=new int*[n];E(d);E(a);R(i)E(b[i]);E(x[i]);E(y[i]); d[i]=0;a[i]=0;R(j)b[i][j]=0;x[i][j]=0;y[i][j]=0;}}if(f(1,0)){R(i)R(j)std::cout<<b[i][j];}std::cout<<std::endl;}}}

여기에서 온라인으로 사용해보십시오

몇 가지 답변이 이미 게시되었으므로 예제의 출력을 생성하는 데 사용되는 골프 버전의 코드를 게시한다고 생각했습니다. 대한 첫 번째 답변 이므로 모든 의견을 환영합니다. :)

언 골프 + 설명 :

본질적으로, 코드는 해결책을 강요합니다. 첫 번째 행에서 0으로 시작합니다. 첫 번째 스팟에서 시작합니다. 해당 스팟이 모든 검사를 통과하면 다음 숫자로 이동합니다. 행을 채우면 다음 행으로 이동합니다. 모든 행이 완료되면 솔루션을 찾았 음을 의미합니다. 스팟이 모든 검사를 통과하지 못하면 다음 스팟으로 이동합니다. 행이 완료되면 이전 행 중 하나의 숫자로 솔루션을 사용할 수 없으므로 역 추적됩니다.

#include <iostream>

// global variables to save bytes on passing these are function arguments
int **b, // this will store the state of the board
    **x, // if x[i][j] is true, row i of b contains the number j
    **y, // if y[i][j] is true, column i of b contains the number j
    *d,  // if d[i] the main diagonal of b contains i
    *a,  // if a[i] the antidiagonal of a contains i
    n;

// preprocessor to save bytes on repeated statements
#define R(i) for(i=0;i<n;i++){
#define E(e) e=new int[n];

// Recursively looks for a solution 
// c - the current number to insert in row r
// r - the current row to fill
int f (int c, int r) {
        int i=0,p=c-1;
        if (r >= n) return 1;             // we are done
        if (c == n + 1) return f(1,r+1);  // this row is full, move to the next row
        R(i)                              // go through the positions in this row,
                                                                            // trying to fill them with c
                int m=r==i, s=r+i==n-1;   // check if this position (r,i) is on ones
                                                                            // of the diagonals
                // if this spot isn't filled, and the row (r), column (i) and diagonals
                // (if it's on the diagonal) doesn't contain the number, fill the spot
                if (!b[r][i] && !x[r][p] && !(m&&d[p]) && !(s&&a[p]) && !y[i][p]) {
                        // fill the spot, and indicate that this row, column and diagonals 
                        // contain this number, c
                        b[r][i]=c; x[r][p]=1; y[i][p]=1;
                        if (m) d[p]=1; if (s)a[p]=1;

                        // move onto to the next number, if you find a solution, stop
                        if (f(c+1,r)) return 1;

                        // with this number in this spot, a solution is impossible, clear
                        // its, and clear the checks
                        b[r][i]=0; x[r][p]=0; y[i][p]=0;
                        if (m) d[p]=0; if (s) a[p]=0;
                }
        }

        return 0; // a solution wasn't found
}

int main() {
        std::cin >> n; // get n from STDIN

        // initialization 
        int i=0,j=0;
        b=new int*[n]; x=new int*[n]; y=new int*[n];
        E(d); E(a);
        R(i)
                E(b[i]); E(x[i]); E(y[i]); // initialization the inner arrays of b, x, y
                d[i]=0; a[i]=0;

                R(j)
                        b[i][j]=0; x[i][j]=0; y[i][j]=0; // ensure each point is initialized as 0
                }
        }

        // find a solution starting at the top-left corner and print it if it finds one
        if (f(1,0)) {
                R(i)
                        R(j)
                                std::cout<<b[i][j];
                        }
                        std::cout<<std::endl;
                }
        }
}

코드를 다시 읽은 후와 같은 검사가 필요하지 않을 수도 있음을 깨달았습니다 if (x[r][p]) return f(c+1,r);. 나는 그것을 단축하기 위해 노력하고 있습니다.
hargasinski

0

클로저, (215 + 258) * 0.8 = 378.4 (174 + 255) * 0.8 = 343.2

오류 계산 STabu 검색을 통해 실제 최적화를 수행하는 익명 함수의 두 부분으로 나뉩니다 .

업데이트 : 짧아지고 S(그룹 내에서 고유 한 값을 계산) 최적의 시작 상태가 아닙니다 (셔플 없음).

(defn S[I n](count(mapcat set(vals(apply merge-with concat(flatten(for[R[(range n)]i R j R v[[(I(+(* n i)j))]]][{[1 i]v}{[2 j]v}(if(= i j){3 v})(if(=(- n 1 i)j){4 v})])))))))
#(if-let[s({1[0]2()3()}%)]s(loop[I(vec(for[R[(range %)]i R j R]i))P #{}](let[[s I](last(sort-by first(for[R[(range(count I))]i R j R I[(assoc(assoc I i(I j))j(I i))]:when(not(P I))][(S I %)I])))](if(=(*(+(* % 2)2)%)s)(partition % I)(recur I(conj P I))))))

4, 5, 6 및 7에 대한 단일 코어 벤치 마크 (밀리 초)는 3 번 실행됩니다.

[[  131.855337   132.96267    138.745981]
 [ 1069.187325  1071.189488  1077.339372]
 [ 9114.736987  9206.65368   9322.656693]
 [36546.309408 36836.567267 36928.346312]]

기발한:

(defn S[I n](apply +(flatten(for[p(concat(partition n I)(for[p(apply map vector(partition n(range(count I))))](map I p))[(take-nth(inc n)I)][(rest(butlast(take-nth(dec n)I)))])](remove #{1}(vals(frequencies p)))))))
#(if-let[s({1[0]2()3()}%)]s(loop[I(vec(flatten(map shuffle(repeat %(range %)))))P #{}](let[[s I](first(sort-by first(for[R[(range(count I))]i R j R I[(assoc(assoc I i(I j))j(I i))]:when(not(P I))][(S I %)I])))](if(= s 0)(partition % I)(recur I(conj P I))))))

나는 S더 짧았 으면 좋았지 만, 하나 이상의 / 파티션의 발생만을 계산하기 때문에 중지 기준은 간단 (= s 0)합니다.

당신이 교환 경우는 점수를 향상되지 않습니다 예를 들어 많은 CPU 사이클, 비 유용 스왑에 대한 낭비 2와 함께 2, 그들은 모두로 시작하는 고유 한 값을 가지고 당신은 행 사이 스왑 번호가 필요하지 않습니다.

Intel 6700K의 벤치 마크 (밀리 초) :

(defn S[I n]( ... )
(def F #( ... ))

(defmacro mytime[expr]
  `(let [start# (. System (nanoTime)) ret# ~expr]
     (/ (double (- (. System (nanoTime)) start#)) 1000000.0)))

(pprint(vec(for[n[4 5 6 7]](vec(sort(repeatedly 5 #(mytime (F n)))))))

[[  43.445902   45.895107   47.277399   57.681634    62.594037]
 [ 222.964582  225.467034  240.532683  330.237721   593.686911]
 [2285.417473 2531.331068 3002.597908 6361.591714  8331.809410]
 [3569.62372  4779.062486 5725.905756 7444.941763 14120.796615]]

멀티 스레드 pmap:

[[   8.881905  16.343714   18.87262  18.9717890   22.194430]
 [  90.963870 109.719332  163.00299  245.824443  385.365561]
 [ 355.872233 356.439256 1534.31059 2593.482767 3664.221550]
 [1307.727115 1554.00260 2068.35932 3626.878526 4029.543011]]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.