Yüz tanıma


43

Bu görevin amacı, herhangi bir 'görüntüdeki' tüm yüzleri tanımlamak, temizlemek ve işaretlemek.

Yüzünde ne var?

Yüz, Z'nin 1'den büyük bir tam sayı olduğu ZxZ karesi olacak. Sol üst ve sağ üst köşeler ve merkez 'O' karakterleri olacak ve alt çizgi ise yeterince '' 've' 'çevreleyen olacak Satırın kalanını doldurmak için '_' karakterleri. Örnekler:

3x3 bir yüz:

O O
 O
\_/

5x5 yüz:

O   O

  O

\___/

7x7 bir yüz:

O     O


   O


\_____/

vb.

Giriş

Girdi, STDIN'de olacak ve birkaç eşit uzunluktaki karakter dizisinden oluşacaktır.

Çıktı

Çıktı, tanınabilir tüm yüzleri temizlenmiş (yani gözler, burun ve ağız şeridi dışındaki tüm karakterler yüz sınırları içinden çıkarılacak) ve kutulu (+, - ve | karakterleriyle çevrili) girdi olmalıdır. İki veya daha fazla yüzün üst üste geldiği yerlerde, her ikisi de temizlenmeli ve kutulanmalı, ancak daha büyük yüze öncelik verilmelidir (üstüne yerleştirilmelidir); iki yüzün de aynı boyutta olması durumunda, öncelik uygulayıcının takdirine bırakılır. Girişin yüzü yoksa, çıkış girişle aynı olmalıdır.

Bazı örnekler

Giriş:

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

Çıktı:

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

Giriş (eksik yüz):

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

Çıktı:

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

Giriş (iç içe geçmiş yüzler):

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

Çıktı:

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

Giriş (çoklu yüzler):

~{$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&^

Çıktı:

+---+*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&^

Giriş (sınırın yakınında):

~{$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&^

Çıktı:

---+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&^

Giriş (örtüşen yüzler):

~{$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&^

Çıktı:

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

Yapışık yüzler (örneğin O'nun sol göz ve sağ göz olarak ikiye katlandığı yerler)? Bunlara üst üste binmiş gibi davranılmalı mı?
Joey Adams,

@Joey Adams: Bu son örnekte olur.
Lowjacker

@Joey Adams @Lowjacker Evet, tıpkı son örnek gibi.
Gareth,

3x3 yüzünü gerçekçi buluyorum ve 7x7 yüz derp. Sadece benim görüşüm. Ben bountiez ... :) kazanmak için zamanım yok o Sad
tomsmeding

2
@tomsmeding Eğer 3x3 yüzünü gerçekçi bulursanız, ilişki kurduğunuz insanları görmekten nefret ederim. : - \
Gareth

Yanıtlar:


19

Ruby, 304 298 295 karakter

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

Yüzler aynı büyüklükte ise üst üste binmede sağ alt tercih edilir. Örneğin giriş için

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

dört yüzü ve verimi tanır

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

Düzenleme 1: Lowjacker'ın önerdiği gibi index, bir regex eşleşmesi (-3 karakter) ile değiştirebiliriz. Dahası, +1eşleştirmeden önce başka bir karakter kazandıran ek bir boş karakter ile telafi edilebilir ( +1köşeli para için -2, + için sahte, -2, parantezler artık gerekli değildir). Bu seriyi parantez olmadan da yazabildiğimizden iki kişi daha.

Düzenleme 2: Her ikisi de ifile değiştirilerek kaydedilen bir başka iki karakter , &&bir diğeri ise aralığı tamamen kaldırarak.


Üçüncü satır (O=~/$/)yerine kullanabilirsiniz O.index($/)(3 karakter kaydeder).
Lowjacker

@Lowjacker Teşekkürler. Numaramla bir tane daha kazanabilirim (düzenlememe bakın).
Howard,

Bence ififadeleri değiştirerek 2 karakter kaydedebilirsiniz &&.
Lowjacker

4

Python - 1199 941

Sorunu oldukça ilginç buldum, bu yüzden Python'da çözdüm. İşte sıkıştırılmış kod.

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

İşte daha okunabilir kod:

#!/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
Lütfen cevabınıza bu versiyonun üzerinde golf versiyonunuzu ekleyiniz. Bu bir kod-golf sorusudur ve en azından golf oynamaya çalışmadıysanız oy kullanma riskiniz vardır. Okunabilir versiyonunuzu burada da bırakabilirsiniz.
Gareth

1
Doğru, @ Gareth. Sık sık golf dostu olmayan Java'ya sık sık çözümler yazıyorum, ancak her zaman alıştırma için golf oynamak için zaman ayırıyorum (hem egzersiz yapmak (karakterleri kısmak ve toplam uzunluğu azaltmak için eğlenceli yollar düşünmek hem de eğlenceli) code-golf (çözümünüzü olabildiğince özlü bir şekilde alıyor). Bu yüzden, golf çözümünüzü görmek için sabırsızlanıyorum, sgauria!
ProgramcıDan

Gareth & @ProgrammerDan teşekkürler! Bu iyi bir tavsiye - kodgolf konusunda oldukça yeniyim. Daha uzun süren çözümlere ek olarak golflü çözümümü ekledim.
sgauria
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.