Pizzaları aynı dilimler halinde kesin


16

Tam olarak okumadan önce bu sorunun olacağını sanıyordum .

Kod golfçüler bir grup Ondokuzuncu Bite Pizzeria yürümek ve bir pizza sipariş. Birim karelerden oluşan düzensiz bir şekilde gelir. Göreviniz, onları aynı dilimler halinde kesmelerine yardımcı olmaktır. Yani, dilimler aynı şekle ve boyuta sahip olmalıdır; döndürülebilir ancak çevrilemez / yansıtılamaz. Örneğin, Tetris parçalarıysa, aynı tür olmalılar, hem L parçası hem de J parçası kullanamazsınız.

Giriş

İlk satırdaki gruptaki kişi sayısına (her zaman 2 ila 10, dahil) bir tam sayı ve ardından pizzayı temsil eden dikdörtgen bir '' (boşluk) ve '#' karakter matrisi verilir. Tüm '#' karakterleri kenarlarından bağlanır. '#' Karakter sayısının kişi sayısının katı olduğu garanti edilir.

Çıktı

Aynı matrisi yazdırmalısınız, her '#' karakteri 0 ile n-1 arasında bir rakamla değiştirilmelidir (n kişi sayısıdır). Her basamak bir dilim işaretlemelidir. Dilim şekli kare kenarlardan bağlanmalıdır. Dilim numaralandırmasının belirli bir sırada olması gerekmez. Pizzayı kesmenin birden fazla yolu varsa, bunlardan herhangi biri kabul edilebilir.
Pizzayı gerektiği gibi kesmek mümkün değilse, "Sizin için pizza yok!" yerine.

puanlama

Bu kod golf. Skorunuz programdaki bayt sayısı olacaktır. Karakterler UTF-8 kodlamaları ile sayılacaktır. En düşük puan kazanır.

Örnekler

Giriş:

3
 #  
### 
####
   #

Çıktı:

 0  
100 
1122
   2

Giriş:

4
###
# #
###

Çıktı:

001
2 1
233

Giriş:

2
#    #
######

Çıktı:

No pizza for you!

Giriş:

5
    #  
   ####
  #####
 ##### 
#####  
####   
  #    

Çıktı:

    0  
   1000
  21110
 32221 
43332  
4443   
  4    

Giriş:

4
   #   
 ####  
###### 
  #####
  #### 

Çıktı:

   0   
 1000  
111203 
  12233
  2233 

Gereksinimler

  • Standart girdiden okuyan ve standart çıktıya yazan tam bir program yazmalısınız.
  • Program, Linux'ta serbestçe kullanılabilen yazılımlar kullanılarak çalıştırılabilir olmalıdır.
  • Programınız, yukarıdaki örneklerin her birini modern bir bilgisayarda 1 dakikadan daha kısa sürede bitirmelidir.
  • Standart boşluklar yok.

3
Ondokuzuncu Isırık : ^)
FryAmTheEggman

@FryAmTheEggman © Calvin'in Hobileri
aditsu çıkmak SE çünkü EVIL

Normal ifade çözümleri için bonus.
flawr

Yanıtlar:


3

PHP kodu, 1808 971 bayt

PHP'de hızlı ve kirli uygulama. Önce kaba kuvvet olası tüm dilim şekilleri, sonra kaba kuvvet tüm dilimlerin konumlarını ve yönlerini.

Kullanımı: cat pizza.txt | php pizza.php

Düzenleme: iç içe döngüler yerine özyineleme kullanarak algoritmayı yeniden yazarak kod boyutunu% 45'den fazla azalttı. Ancak, bu bellek (ve pizza'nın ;-)) yiyor. Pizza 8x8'den daha büyük olasılıkla hafızada bitecek. İç içe döngü değişkeni herhangi bir boyutu kolayca işleyebilir, ancak kod boyutunun iki katıdır.

<?php define('A',98);$n=fgets(STDIN);$d=array();$m=$u=str_pad('',A,'+');$s=0;while($g=fgets(STDIN)){$g=rtrim($g);assert(strlen($g)<=A-2);$s++;$m.='+'.str_pad(rtrim($g),A-2,' ').'+';for($l=0;$l<strlen($g);$l++)if($g[$l]=='#')$d[]=$s*A+$l+1;}$m.=$u;$r=count($d)/$n;x(reset($d),array(array()),0,0,0,0);die('No pizza for you!');function x($e,$c,$b,$a,$q,$t){global$r,$m,$d;$h=$a*A+$b;if(!in_array($e+$h,$d))return;if(in_array($h,$c[0]))return;$c[0][]=$h;$c[1][]=$b*A-$a;$c[2][]=-$a*A-$b;$c[3][]=-$b*A+$a;if(count($c[0])<$r)do{x($e,$c,$b+1,$a,$b,$a);x($e,$c,$b,$a+1,$b,$a);x($e,$c,$b-1,$a,$b,$a);x($e,$c,$b,$a-1,$b,$a);$v=($b!=$q||$a!=$t);$b=$q;$a=$t;}while($v);else w($c,$m,0,reset($d),0);}function w(&$p,$f,$o,$e,$i){global$n,$d;foreach($p[$i]as$h){$j=$e+$h;if(!isset($f[$j])||$f[$j]!='#')return;$f[$j]=chr(ord('0')+$o);}if(++$o==$n){for($k=A;$k<strlen($f)-A;$k++)if($k%A==A-1)echo PHP_EOL;else if($k%A)echo$f[$k];exit;}foreach($d as$j)for($i=0;$i<4;$i++)w($p,$f,$o,$j,$i);}

Ungolfed, belgelenmiş kod

Aşağıda belgelenmiş orijinal kod bulunmaktadır. Akıl sağlığımı kulak olsun diye tam kaynak kodu ile çalıştı ve benzeri ifadeleri şerit basit minifier senaryoyu yazdım assert()ve error_reporting()yukarıda golfed kodu oluşturmak için gereksiz parantez, yeniden adlandırma değişkenleri, fonksiyonları ve sabitler kaldırın.

<?php
error_reporting(E_ALL) ;

// Width of each line of pizza shape.
// Constant will be reduced to single character by minifier,
// so the extra cost of the define() will be gained back.
define('WIDTH', 98) ;

// Read number of slices
$nrSlices = fgets(STDIN) ;

// Read pizza shape definition and 
// convert to individual $positionList[]=$y*width+$x and
// linear (1D) $pizzaShape[$y*WIDTH+$x] with protective border around it.
//
// WARNING: assumes maximum pizza width of WIDTH-2 characters!
$positionList = array() ;
$pizzaShape = $headerFooter = str_pad('', WIDTH, '+') ;
$y = 0 ;
while ($line = fgets(STDIN))
{  $line = rtrim($line) ;
   assert(strlen($line) <= WIDTH-2) ;
   $y++ ;
   $pizzaShape .= '+'.str_pad(rtrim($line), WIDTH-2, ' ').'+' ;
   for ($x = 0 ; $x < strlen($line) ; $x++)
   {  if ($line[$x] == '#') $positionList[] = $y*WIDTH + $x+1 ;
   }
}
$pizzaShape .= $headerFooter ;

// Determine size of a slice
$sliceSize = count($positionList)/$nrSlices ;

// Build all possible slice shapes. All shapes start with their first part at 
// the top of the pizza, and "grow" new parts in all directions next to the 
// existing parts. This continues until the slice has the full size. This way
// we end up with all shapes that fit at the top of the pizza.
//
// The shape is defined as the offsets of the parts relative to the base 
// position at the top of the pizza. Offsets are defined as linear offsets in
// the 1-D $pizzaShape string.
//
// For efficiency, we keep track of all four possible rotations while building
// the slice shape.
//
growSlice(reset($positionList), array(array()), 0, 0, 0, 0) ;
die('No pizza for you!') ;

function growSlice($basePosition, $shapeDeltas, $dx, $dy, $prevDx, $prevDy)
{  global $sliceSize, $pizzaShape, $positionList ;

   // Check validity of new position
   // Abort if position is not part of pizza, or 
   // if position is already part of slice
   $delta = $dy*WIDTH + $dx ;
   if (!in_array($basePosition+$delta, $positionList)) return ;
   if (in_array($delta, $shapeDeltas[0])) return ;

   // Add all four rotations to shapeDeltas[]
   $shapeDeltas[0][] = $delta ;
   $shapeDeltas[1][] = $dx*WIDTH - $dy ;
   $shapeDeltas[2][] = -$dy*WIDTH - $dx ;
   $shapeDeltas[3][] = -$dx*WIDTH + $dy ;

   // Have we built a full slice shape?
   if (count($shapeDeltas[0]) < $sliceSize) 
   {  // Grow shape either at current position or at previous position
      do
      {  growSlice($basePosition, $shapeDeltas, $dx+1, $dy,   $dx, $dy) ;
         growSlice($basePosition, $shapeDeltas, $dx,   $dy+1, $dx, $dy) ;
         growSlice($basePosition, $shapeDeltas, $dx-1, $dy,   $dx, $dy) ;
         growSlice($basePosition, $shapeDeltas, $dx,   $dy-1, $dx, $dy) ;
         $retry = ($dx != $prevDx || $dy != $prevDy) ;
         $dx = $prevDx ;
         $dy = $prevDy ;
      } while ($retry) ;
   } else
   {  // Try to cover the entire pizza by translated and rotated instances of
      // the slice shape.
      fitSlice($shapeDeltas, $pizzaShape, 0, reset($positionList), 0) ;
   }
}

function fitSlice(&$shape, $pizza, $id, $basePosition, $rotation)
{  global $nrSlices, $positionList ;

   // Try to fit each part of the slice onto the pizza. If the part falls
   // outsize the pizza, or overlays another slice we reject this position
   // and rotation. If it fits, we mark the $pizza[] with the slice $id.
   foreach ($shape[$rotation] as $delta)
   {  $position = $basePosition + $delta ;
      if (!isset($pizza[$position]) || $pizza[$position] != '#') return ;
      $pizza[$position] = chr(ord('0')+$id) ;
   }

   // If $nrSlices slices have been fitted, we have found a valid solution!
   // In that case, we display the solution and quit.
   if (++$id == $nrSlices)
   {  for ($pos = WIDTH ; $pos < strlen($pizza)-WIDTH ; $pos++)
      {  if ($pos % WIDTH == WIDTH-1) echo PHP_EOL ;
         else if ($pos % WIDTH) echo $pizza[$pos] ;
      }
      exit ;
   }

   // The current slice did fit, but we have still more slices to fit.
   // Try all positions and rotations for the next slice.
   foreach ($positionList as $position)
   {  for ($rotation = 0 ; $rotation < 4 ; $rotation++)
      {  fitSlice($shape, $pizza, $id, $position, $rotation) ;
      }
   }
}

"PHP Ölümcül hata: satır 1 pizza.php içinde _ () yeniden bildirilemiyorum"
alıyorum

@aditsu: golf edilmiş versiyonda sadece bir fonksiyon _ () vardır. Kodu yanlışlıkla iki kez kopyalayıp yapıştırdınız mı?
Jason Smith

Dosya boyutu 972 olduğundan, kodun iki kez sığabileceğini sanmıyorum. Çözümsüz kod btw gibi görünüyor :)
aditsu çıkın çünkü SE kötü

Sahip olduğunuzu fark ettim define('_',98), bu çatışma değil function _mi? Ben php bilmiyorum bu yüzden söyleyemem ...
aditsu çıkın çünkü SE EVIL

@aditsu: Golfçü kod PHP 5.4.43 ile Mac'imde iyi çalışıyor, ancak _ () diğer platformlarda gettext () için bir takma ad olarak görünüyor. _ () ​​İşlevini tamamen önlemek için küçültücü değiştirildi.
Jason Smith
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.