안면 인식


43

이 작업의 목적은 주어진 '이미지'에서 모든 얼굴을 식별, 정리 및 표시하는 것입니다.

얼굴이 뭐야?

면은 ZxZ 정사각형이되며 여기서 Z는 1보다 큰 홀수 정수입니다. 왼쪽 위와 오른쪽 모서리와 가운데는 'O'문자가되고 맨 아래 줄은 '\'와 '/'가됩니다. 나머지 줄을 채우려면 '_'문자 예 :

3x3 얼굴 :

O O
 O
\_/

5x5 얼굴 :

O   O

  O

\___/

7x7 얼굴 :

O     O


   O


\_____/

기타

입력

입력은 STDIN에 있으며 여러 개의 동일한 길이의 문자열로 구성됩니다.

산출

출력은 인식 할 수있는 모든 얼굴이 지워지고 (즉, 눈, 코 및 입을 제외한 모든 문자가 얼굴 경계 내에서 제거됨) 상자로 채워진 입력이어야합니다 (+,-및 | 문자로 둘러싸여 있음). 두 개 이상의면이 겹치는 경우 두면을 모두 지우고 상자에 넣어야하지만 더 큰면에 우선 순위를 두어야합니다 (위에 배치해야 함). 두면의 크기가 모두 같은 경우 우선 순위는 구현 자의 재량에 달려 있습니다. 입력에면이 없으면 출력은 입력과 같아야합니다.

몇 가지 예

입력:

*******
*******
**O*O**
***O***
**\_/**
*******
*******

산출:

*******
*+---+*
*|O O|*
*| O |*
*|\_/|*
*+---+*
*******

입력 (불완전한 얼굴) :

*******
*******
**O*O**
*******
**\_/**
*******
*******

산출:

*******
*******
**O*O**
*******
**\_/**
*******
*******

입력 (중첩면) :

*******
*O***O*
**O*O**
***O***
**\_/**
*\___/*
*******

산출:

+-----+
|O   O|
|     |
|  O  |
|     |
|\___/|
+-----+

입력 (여러면) :

~{$FJ*TBNFU*YBVEXGY%
FOCO$&N|>ZX}X_PZ<>}+
X$OOPN ^%£)LBU{JJKY%
@\_/$£!SXJ*)KM>>?VKH
SDY%£ILO(+{O:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJO$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@\___/GER%^*BI
@{PO{_):<>KNUYT*&G&^

산출:

+---+*TBNFU*YBVEXGY%
|O O|&N|>ZX}X_PZ<>}+
| O |N ^%£)LBU{JJKY%
|\_/|£+-----+M>>?VKH
+---+I|O   O|HO(UR$W
XVBFTE|     |LO*(&P:
>?LKPO|  O  |&L:}~{&
~@?}{)|     |@~}P>OU
:@<L::|\___/|ER%^*BI
@{PO{_+-----+YT*&G&^

입력 (경계 근처) :

~{$FJ*TBNFU*YBVEXGY%
OCO$&N|>ZX}X_PZ<>}+^
$OOPN ^%£)LBU{JJKY%{
\_/$£!SXJ*)KM>>?VKHU
SDY%£ILO(+{8:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJ^$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@BJYT*GER%^*BI
@{PO{_):<>KNUYT*&G&^

산출:

---+J*TBNFU*YBVEXGY%
O O|&N|>ZX}X_PZ<>}+^
 O |N ^%£)LBU{JJKY%{
\_/|£!SXJ*)KM>>?VKHU
---+£ILO(+{8:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJ^$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@BJYT*GER%^*BI
@{PO{_):<>KNUYT*&G&^

입력 (겹치는면) :

~{$FJ*TBNFU*YBVEXGY%
FXC£$&N|>ZX}X_PZ<>}+
X$*OPN O%£)LBO{JJKY%
@:U%$£!SXJ*)KM>>?VKH
SDY%£OLO(+{P:HO(UR$W
XVBFTER^&IOLNLO*(&P:
>?L\___/JR$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@\_____/R%^*BI
@{PO{_):<>KNUYT*&G&^

산출:

~{$FJ*TBNFU*YBVEXGY%
FX+---+-------+Z<>}+
X$|O  |O     O|JJKY%
@:|   |       |>?VKH
SD|  O|       |(UR$W
XV|   |   O   |*(&P:
>?|\__|       |:}~{&
~@+---|       |}P>OU
:@<L::|\_____/|%^*BI
@{PO{_+-------+*&G&^

결합 된 얼굴은 어떻습니까 (예 : O가 왼쪽 눈과 오른쪽 눈으로 두 배가되는 경우)? 그것들을 겹치는 것으로 취급해야합니까?
Joey Adams

@Joey Adams : 마지막 예제에서 발생합니다.
Lowjacker

@Joey Adams @Lowjacker 예, 마지막 예와 같습니다.
Gareth

3x3 얼굴이 사실적이고 7x7 얼굴이 엉망이라는 것을 알았습니다. 그냥 내 의견. bountiez를 얻을 시간이 없어서 슬프다 ... :)
tomsmeding

2
@tomsmeding 만약 당신이 3x3 얼굴을 현실적으로 본다면 당신이 관계하는 사람들을보고 싶어하지 않을 것입니다. :-\
Gareth

답변:


19

루비, 304 298 295 자

I=$<.read
q=(O=I*s=1).size
k=??+O=~/$/
o=->m,n{n.chars{|c|(m+=1)*(m%k)>0&&m<q&&O[m-1]=c}}
q.times{f=[[?\\+?_*s+?/,k*s+=1],[?O,0],[?O,s],[?O,(s+=1)/2*(1+k)]]
q.times{|x|f.all?{|a,b|I[x+b,a.size]==a}&&(o[x+k*s-1,o[x-k-1,?++?-*s+?+]]
s.times{|a|o[x+k*a-1,?|+' '*s+?|]}
f.map{|a,b|o[x+b,a]})}}
$><<O

면의 크기가 동일한 경우 오른쪽 아래가 겹치는 것이 좋습니다. 예를 들어 입력

O.OO.O
.O..O.
\_/\_/
O.OO.O
.O..O.
\_/\_/

그것은 네 얼굴과 수율을 모두 인식

O |O O
 O| O
--+---
O |O O
 O| O
\_|\_/

편집 1 : Lowjacker가 제안한대로 index정규식 일치 (-3 문자)로 바꿀 수 있습니다 . 또한 +1일치하기 전에 추가 더미 문자로 보완하여 다른 문자를 절약 할 수 있습니다 ( +1더블 문자는 -2, 더미 문자는 +3, 더 이상 괄호가 필요하지 않으므로 -2). 대괄호없이 범위를 쓸 수 있기 때문에 두 개 더.

편집 2 : 모두를 대체하여 저장 한 또 다른 두 개의 문자 if&&다른 하나는 완전히 범위를 제거.


세 번째 줄 (O=~/$/)대신 사용할 수 있습니다 O.index($/)(3 자 절약).
Lowjacker

@Lowjacker 감사합니다. 나는 당신의 트릭으로 하나 더 저장할 수 있습니다 (내 편집 참조).
Howard

if문을 로 바꾸면 2자를 저장할 수 있다고 생각합니다 &&.
Lowjacker

4

파이썬 -1199 941

나는 문제가 꽤 흥미로워 서 파이썬으로 해결했다. 압축 된 코드는 다음과 같습니다.

#!/usr/bin/env python
import fileinput,sys
m=[[c for c in l if c!='\n'] for l in fileinput.input()]
X=len(m[0])
Y=len(m)
t=[]
for n in range(3,min(X,Y)+1,2):
  for x in range(X-n+1):
    for y in range(Y-n+1):
      if m[y][x]=='O' and m[y][x+n-1]=='O' and m[y+(n//2)][x+(n//2)]=='O' and m[y+n-1][x]=='\\' and m[y+n-1][x+n-1]=='/' and "".join(m[y+n-1][x+1:x+n-1])=='_'*(n-2):
        t.append((x,y,n))
for x,y,n in t:
  def a(v,h,c):
    w=x+h; z=y+v;
    if z>=0 and z<len(m):
      if w>=0 and w<len(m[y]):
        m[z][w]=c
  for v in range(n):
    for h in range(n): 
      a(v,h,' ')
  a(0,0,'O')
  a(0,n-1,'O')
  a(n/2,n/2,'O')
  a(n-1,0,'\\')
  a(n-1,n-1,'/')
  for w in range(1,n-1):
    a(n-1,w,'_')
  for v in [-1,n]:
    for h in range(n):
      a(v,h,'-')
  for h in [-1,n]:
    for v in range(n):
      a(v,h,'|')
  a(-1,-1,'+')
  a(-1,n,'+')
  a(n,-1,'+')
  a(n,n,'+')
for l in m:
  for c in l:
    sys.stdout.write(c)
  print

더 읽기 쉬운 코드는 다음과 같습니다.

#!/usr/bin/env python

import fileinput, sys

matrix = [[c for c in l if c != '\n'] for l in fileinput.input()]

max_X = len(matrix[0])
max_Y = len(matrix)

tuples = []
for n in range(3, min(max_X, max_Y)+1, 2):
  for x in range(max_X-n+1):
    for y in range(max_Y-n+1):
      # if is_face(matrix, x, y, n):
      if matrix[y][x] == 'O' and matrix[y][x+n-1] == 'O' and matrix[y+(n//2)][x+(n//2)] == 'O' and matrix[y+n-1][x] == '\\' and matrix[y+n-1][x+n-1] == '/' and "".join(matrix[y+n-1][x+1:x+n-1]) == '_'*(n-2) :
        tuples.append((x, y, n))

for x,y,n in tuples:
  # blank_and_border(matrix,x,y,n)
  def assign(dy, dx, c):
    xx = x + dx; yy = y + dy;
    if yy >= 0 and yy < len(matrix) :
      if xx >= 0 and xx < len(matrix[y]) :
        matrix[yy][xx] = c

  # blank
  for dy in range(n):
    for dx in range(n): 
      assign(dy, dx, ' ')

  # face
  assign(0, 0, 'O')
  assign(0, n-1, 'O')
  assign(n/2, n/2, 'O')
  assign(n-1, 0, '\\')
  assign(n-1, n-1, '/')
  for w in range(1,n-1):
    assign(n-1, w, '_')

  # border
  for dy in [-1,n]:
    for dx in range(n):
      assign(dy, dx, '-')

  for dx in [-1,n]:
    for dy in range(n):
      assign(dy, dx, '|')

  assign(-1, -1, '+')
  assign(-1,  n, '+')
  assign( n, -1, '+')
  assign( n,  n, '+')

for l in matrix:
  for c in l:
    sys.stdout.write(c)
  print

2
답변에서 골프 버전을이 버전 위에 추가하십시오. 이것은 코드 골프 질문이며 적어도 골프를 치려고 시도하지 않으면 투표권을 잃을 위험이 있습니다. 읽을 수있는 버전도 여기에 둘 수 있습니다.
Gareth

1
바로 @Gareth. 나는 종종 골프에 친숙하지 않은 Java로 솔루션을 작성하지만 항상 운동 (문자를 자르고 전체 길이를 줄이는 방법을 생각하는 재미)과 코드 골프 (가능한 한 간결한 솔루션을 얻음). 그래서 골프 솔루션, sgauria를 기대!
ProgrammerDan

감사합니다 Gareth & @ProgrammerDan! 좋은 충고입니다. 저는 codegolf에 익숙하지 않습니다. 더 긴 솔루션 외에도 위의 골프 솔루션을 추가했습니다.
sgauria
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.