헥소 미노를 큐브로 접을 수 있습니까?


24

내 아이가 가장 좋아하는 장난감 중 하나는 이와 같은 세트 입니다. 실제로 제가 가장 좋아하는 장난감 중 하나입니다. 나는 그 장난감을 가지고 놀았고 PPCG 도전 아이디어를 내게주었습니다. 여기 하나가 있습니다 :

ASCII 선 그리기를 입력으로 사용하여 큐브로 접을 지 여부를 결정하는 프로그램 또는 함수를 작성하십시오.

입력

입력은 다음과 같이 정사각형으로 만들어진 정확히 하나의 헥소 미노로 구성됩니다.

+-+
| |
+-+

예를 들어 유효한 입력 헥시 미노는 다음과 같습니다.

+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
  | |
  +-+

산출

  • 헥소 미노를 입방체로 접을 수있는 경우 진실한 가치
  • 그렇지 않으면 거짓 값입니다.

우리에게 약간의 작업을 저장하기 위해 wikipedia에는 ​​다음과 같은 멋진 그래픽이 있습니다.

  • 모든 35 헥소 미노 :

  • 큐브로 접히는 11 개의 헥소 미노 :

노트

  • 입력 헥 소미 노는 위 이미지에 표시된 것뿐만 아니라 회전 또는 반사가있을 수 있습니다.
  • 입력 헥소 미노에는 선행 공백이있을 수 있지만 자신과 관련하여 올바르게 정렬됩니다.
  • 입력 헥 소미 노는 줄 끝에 후행 공백이 있고 입력 끝에 줄 바꿈이있을 수 있습니다.

1
여기에 이미지 처리 태그가있는 이유를 설명 할 수 있습니까? 질문도 답도 도전을 해결하기 위해 어떤 종류의 이미지 처리도하지 않아도됩니다.
Optimizer

선행 / 트레일 공간에 대한 설명 : 각 행에 불필요한 선행 / 트레일 공간이 있고 입력에 불필요한 줄 바꿈이 허용됩니까? 1000 개 이상의 문자 입력을 관리 할 수 ​​있어야합니까?
edc65

@ edc65 네, 당신은 당신이 묘사하는 불필요한 공백을 기대해야합니다. 최대 1000 자까지 입력 할 수있는 것 같습니다. 다음에서 수정하겠습니다.
Digital Trauma

흠. 인쇄 된 페이지에서 얼마나 많은 큐브 헥소 미노를 압착, 병치 할 수 있는지 궁금합니다.
luser droog

답변:


7

PMA / 달팽이 , 130

.!(z\ |o{c..!(z\ }3){w=(..!(z\ )|b..!(z\ )o{..!(z\ }2|c{..!(z\ }1,2w..!(z\ )|w{..!(z\ }1,2c..!(z\ }4o..!(z\ )(..!(z\ )|n..!(z\ )`2

더 "읽을 수있게"

?
.!(z\  | o{c..!(z\ }3  )
{w =( ..!(z\ ) | b ..!(z\ ) o {..!(z\ }2  | c {..!(z\ }1,2w..!(z\ ) | w {..!(z\ }1,2c..!(z\  }4
o  ..!(z\ ) ( ..!(z\ ) | n ..!(z\ ) `2

일반적으로 지금까지 구현 된 제한된 기능으로 처리 할 수있는 문제가 발생했습니다. !(z\ )패턴은 현재의 위치가 어떤 "octilinear"방향으로의 공간이 있다는 것을 제외 주장을 이용하여 사각형의 중앙 공간에 있다고 판단한다. 일반적인 아이디어는 경기가 시작되는 사각형을 기준으로 5 개의 필요한 위치 각각에 사각형을 배치하는 패턴을 확인하는 것입니다. 또한 2x2 정사각형 블록에 없는지 확인해야합니다. 프로그램이 작동하기 전에 괄호를 파싱하여 버그를 수정해야했습니다.

헥소 미노가 큐브를 매핑하지 않으면 0인쇄됩니다. 일치하면 일부 양의 정수가 인쇄됩니다 (일치 수).

가능한 모든 테스트 사례를 생성하기 위해이 폴리 노 미노 발생기 를 조정 했습니다 .

n=input()
r=range
T=lambda P:set(p-min(p.real for p in P)-min(p.imag for p in P)*1j for p in P)
A=[]
for i in r(1<<18):
 P=[k%3+k/3*1j for k in r(18)if i>>k&1]
 C=set(P[:1])
 for x in P:[any(p+1j**k in C for k in r(4))and C.add(p)for p in P]
 P=T(P)
 if not(C^P or P in A or len(P)-n):
  #for y in r(4):print''.join(' *'[y+x*1j in P] for x in r(6))
  o = [ [' ']*13 for _ in r(9)]
  for y in r(4):
   for x in r(6):
    if y+x*1j in P: X=2*x;Y=2*y; o[Y][X]=o[Y+2][X]=o[Y][X+2]=o[Y+2][X+2]='+'; o[Y][X+1]=o[Y+2][X+1]='-';o[Y+1][X+2]=o[Y+1][X]='|'
  print '\n'.join(map(''.join,o))
  A+=[T([p*1j**k for p in P])for k in r(4)]

hahahahahahahah 더 "읽을 수있게"
Optimizer

5

루비, 173148145143 바이트

h=->b,c{[c.count(c.max),c.count(c.min),3].max*2<b.max-b.min}
->s{x=[];y=[];i=j=0
s.bytes{|e|e==43&&x<<i|y<<j;i=e<32?0*j+=1:i+1}
h[x,y]||h[y,x]}

최신 변경 사항 : /2오른쪽이 왼쪽 으로 <교체되었습니다 *2. 한 세트의 제거 가능()

설명

코드는 두 부분으로 구성됩니다. 구문 분석을 수행하는 명명되지 않은 기본 함수와 h검사를 수행하는 변수에 할당 된 명명되지 않은 보조 함수 입니다.

x와 y 좌표 추가 스트링 통해 주 스캔 기능의 바이트, i,j모든 +기호는 것을 발견 x[]하고 y[]. 그런 다음 h두 번 호출합니다 . 헥소 미노가 처음으로 수평이라고 가정하면 ( x[]길이와 y[]너비를 포함) 두 번째로 수직으로 가정합니다.

이 함수 h는 배열의 세로 좌표를 취한 b다음 배열 의 가로 좌표를 사용 c합니다. 표현식으로 길이 (제곱)를 계산합니다 (b.max.b.min)/2. 이것이 3 이하인 경우, 헥 소미 노는 다른 방향으로 평가되어야하므로를 h반환합니다 false.

헥소 미노를 검사하면 길이가 4 인 경우 입방체로 접히는 헥 소미 노는 +첫 번째와 마지막 행에서 2 제곱 (3 기호)을 초과하지 않습니다 . 정사각형의 대부분은 가운데 줄에 집중되어 큐브의 적도가됩니다. 이 조건은 입방체로 접히는 길이 4의 헥소 미노에 필요하고 충분한 것으로 판명되었습니다.

입방체로 접히는 길이 5의 헥 소미 노는 하나뿐입니다. +첫 번째 행과 마지막 행에 3 개의 사각형 (4 개의 기호)이 있습니다. 길이가 5 인 다른 모든 헥 소미 노는 +첫 번째 또는 마지막 행에 5 개 이상의 기호가 있습니다.

길이 6의 헥 소미 노는 하나뿐입니다 +. 각 행 에는 7 개의 기호가 있습니다.

이 모든 것을 종합하면 헥소 미노의 길이가 3보다 크고 +첫 번째 및 마지막 행 의 기호 수가 더 길다는 것을 확인하는 것으로 충분합니다 .

테스트 프로그램에서 언 골프

#checking function as explained in text
h=->b,c{[c.count(c.max),c.count(c.min),3].max<(b.max-b.min)/2}

#main function for parsing
f=->s{
  x=[]                 #separate assignments required, 
  y=[]                 #otherwise we get 2 pointers to the same array
  i=j=0                #start coordinates 0,0
  s.bytes{|e|          #scan string bytewise
    e==43&&x<<i|y<<j     #if byte is a + symbol (ascii 43) add the coordinates to arrays x and y
    i=e<32?0*j+=1:i+1    #if byte is before ascii 32 assume newline, increment j and zero i. Otherwise increment i
  }
  h[x,y]||h[y,x]       #call h twice, with x and y in each possible order
}



#VALID INPUTS
puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
| |
+-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
  | |
  +-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
+-+
| |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]

puts f["
+-+
| |
+-+-+-+-+
| | | | |
+-+-+-+-+
      | |
      +-+"]

puts f["
    +-+
    | |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
    +-+
    | |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]


puts f["
  +-+
  | |
+-+-+-+-+
| | | | |
+-+-+-+-+
    | |
    +-+"]
puts f["
  +-+
  | |
+-+-+-+
| | | |
+-+-+-+-+
    | | |
    +-+-+"]  
puts f["
+-+-+
| | |
+-+-+-+
  | | |
  +-+-+-+
    | | |
    +-+-+"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+-+
      | | | |
      +-+-+-+
"]


#INVALID INPUTS

puts f["
  +-+-+-+
  | | | |
  +-+-+-+
  | | | |
  +-+-+-+
"]


puts f["
  +-+-+-+-+-+-+
  | | | | | | |
  +-+-+-+-+-+-+

"]


puts f["
  +-+-+
  | | |
  +-+-+
  | |
  +-+
  | |
  +-+
  | |
  +-+
  | |
  +-+
"]

puts f["
  +-+-+-+-+-+
  | | | | | |
  +-+-+-+-+-+
    | |
    +-+
"]

puts f["
      +-+
      | |
  +-+-+-+-+-+
  | | | | | |
  +-+-+-+-+-+
"]

puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+-+
        | | |
        +-+-+"]

puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
      | | |
      +-+-+
"] 


puts f["
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
  | | | |
  +-+ +-+
"]

puts f["
 +-+   +-+
 | |   | |
 +-+-+-+-+
 | | | | |
 +-+-+-+-+
"]

puts f["
   +-+-+
   | | |
 +-+-+-+-+
 | | | | |
 +-+-+-+-+
"]

puts f["
  +-+
  | |
  +-+
  | |
  +-+-+-+-+
  | | | | |
  +-+-+-+-+
"]

puts f["
  +-+
  | |
  +-+-+-+
  | | | |
  +-+-+-+
  | |
  +-+
  | |
  +-+
"]

puts f["
  +-+
  | |
+-+-+-+
| | | |
+-+-+-+
| |
+-+
| |
+-+"]

puts f["
  +-+-+
  | | |
  +-+-+
  | |
  +-+-+
  | | |
  +-+-+
    | |
    +-+
"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+
    | | | |
    +-+-+-+
"]

puts f["
  +-+-+-+
  | | | |
  +-+-+-+
      | |
      +-+-+
      | | |
      +-+-+
"]


puts f["
  +-+-+-+
  | | | |
  +-+-+-+-+
      | | |
      +-+-+
        | |
        +-+
"]

당신의 텍스트에 pentonimo → hexonimo?
Paŭlo Ebermann

3

자바 스크립트 (ES6), 443 431

편집 빈 열을 제거하는 버그 수정, 입력 구문 분석시 문제

F=t=>(a=b=c=d=e=f=g=h=0,M=Math.min,
t=t.split('\n').filter(r=>r.trim()>''),
t=t.map(r=>r.slice(M(...t.map(r=>r.search(/\S/))))),
t.map((r,i)=>i&1&&[...r].map((_,j)=>j&1&&r[j-1]==r[j+1]&t[i-1][j]==t[i+1][j]&r[j-1]=='|'
&&(y=i>>1,x=j>>1,z=y*5,w=x*5,a|=1<<(z+x),e|=1<<(w+y),b|=1<<(4+z-x),f|=1<<(4+w-y),c|=1<<(20-z+x),g|=1<<(20-w+y),d|=1<<(24-z-x),h|=1<<(24-w-y)
))),~[1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056].indexOf(M(a,b,c,d,e,f,g,h)))

입력 구문 분석이 작업의 큰 부분이므로 매우 길고 더 길어집니다.

주어진 입력이 11 개의 접이식 헥소 미노 중 하나인지 확인하는 것입니다.

각 접이식 헥 소미 노는 5x5 비트 맵에 매핑 할 수 있습니다 (시뮬레이션 및 회전과 함께 최대 8 가지). 비트 맵을 25 비트 숫자로 취한 후 다음 코드를 사용하여 11 개의 헥소 미노에 대한 최소값을 찾았습니다 (매우 간단한 입력 형식).

h=[ // Foldable hexominoes
'o\noooo\no', ' o\noooo\n o', // pink
'o\noooo\n   o', ' o\noooo\n  o', 'ooo\n  ooo', 'oo\n oo\n  oo', //blue
'o\noooo\n o', 'o\noooo\n  o', 'oo\n ooo\n o', 'oo\n ooo\n  o', 'o\nooo\n  oo' // gray
]
n=[]
h.forEach(t=>(
  a=[],
  t.split('\n')
    .map((r,y)=>[...r]
      .map((s,x)=>s>' '&&(
         a[0]|=1<<(y*5+x),a[1]|=1<<(x*5+y),  
         a[2]|=1<<(y*5+4-x),a[3]|=1<<(x*5+4-y),  
         a[4]|=1<<(20-y*5+x),a[5]|=1<<(20-x*5+y),  
         a[6]|=1<<(24-y*5-x),a[7]|=1<<(24-x*5-y))
     )
  ),
n.push(Math.min(...a))
))

그게 [1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056]

따라서 입력 문자열이 주어지면 최소 비트 맵을 찾기 위해 동일한 작업을 수행 한 다음이 숫자가 내 사전 계산 목록에 있으면 true를 반환해야합니다.

// Not so golfed 

F=t=>(  
  a=b=c=d=e=f=g=h=0,M=Math.min,
  t=t.split('\n').filter(r=>r.trim()>''), // remove blank lines
  t=t.map(r=>r.slice(M(...t.map(r=>r.search(/\S/))))), // remove blank colums to the left
  t.map((r,i)=>i&1&&[...r] // only odd rows
   .map((_,j)=>j&1&& // only odd columns
      r[j-1]==r[j+1]&t[i-1][j]==t[i+1][j]&r[j-1]=='|' // found a cell
         &&(y=i>>1,x=j>>1,z=y*5,w=x*5, // find bitmaps for 8 rotations/simmetries
            a|=1<<(z+x),e|=1<<(w+y),  
            b|=1<<(4+z-x),f|=1<<(4+w-y),  
            c|=1<<(20-z+x),g|=1<<(20-w+y),  
            d|=1<<(24-z-x),h|=1<<(24-w-y)  
    ))),
   ~[1505,2530,3024,4578,252,6552,2529,4577,2499,4547,7056].indexOf(Math.min(a,b,c,d,e,f,g,h)) // look for min
)

스 니펫을 실행하여 Firefox에서 테스트


내가 뭔가를 놓쳤다면 용서하십시오.하지만 ,\nt=t두 번째 줄의 끝에서 / 세 번째 줄의 시작에서 당신을 찾을 수 없습니까?
코너 오브라이언

6 개월 후 @ CᴏɴᴏʀO'Bʀɪᴇɴ를 검토하면 파싱 코드는 10 ... 15 바이트 더 짧아 질 수 있습니다. 그대로, 나는 줄 2에서 t에 할당하고 줄 3에서 다시 할당해야합니다. 줄 3에서 왼쪽에서 잘라낼 공백 문자의 수를 찾는 데 사용되기 때문입니다.
edc65
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.