n 개의 노드가있는 모든 이진 트리 열거


10

정수 n이 주어지면 n 개의 내부 노드가있는 모든 가능한 전체 이진 트리를 열거하십시오. 전체 이진 트리에는 모든 내부 노드에 정확히 2 개의 자식이 있습니다. 트리 구조는 트리의 사전 주문 순회로 출력되어야하며 1은 내부 노드를 나타내고 0은 외부 노드를 나타냅니다 (Null).

처음 몇 n에 대한 예는 다음과 같습니다.

0 :
0

1 :
100

2 :
11000
10100

3 :
1110000
1101000
1100100
1011000
1010100

상금이 가장 적은 코드 골프입니다. 나무는 stdout에 한 줄에 하나씩 출력되어야합니다. 프로그램은 명령 행 또는 stdin에서 n을 읽어야합니다.


나는 미로 같은 글쓰기 시스템을 만들려고 할 때 그 문제에 대해 생각하고 있었다
Ming-Tang

솔루션을 선언하기 전에 표준 기한은 얼마입니까?
Kyle Butt

출력을 주문하고 스트리밍해야하는이 문제의 약간의 변형을 수행하는 데 관심이 있습니까?
Kyle Butt

@Kyle Butt 제 의견은 있지만 관심이없는 것 같습니다. 나를 위해, 이러한 문제에 대한 재미의 일부는 다른 접근법을 시도하고 있으며 특정 순서를 요구하면 실행 가능한 알고리즘의 수가 제한 될 수 있습니다.
migimaru

답변:


3

-125 79 자

" -ln"옵션 에는 4 개의 문자가 포함됩니다 . stdin에서 n을 가져옵니다.

새로운 건설적인 접근 방식 :

@a=0;map{%a=();map{$a{"$`100$'"}=1while/0/g;}@a;@a=keys%a}1..$_;print for@a

n-1에 대한 솔루션의 각 트리에서 각 리프 ( "0")에 대해 새 내부 노드 ( "100")를 차례로 대체하여 n에 대한 솔루션을 형성하십시오.

(이 개념은 순차적으로 생성 된 문자열을 확인하기 위해 내부 노드를 사용하여 [100-> 0] 대체를 리프팅하는 다른 솔루션에 빚진 것이며, 그 개념에 따라 답을 작성한 후에도 동일한 0- 누군가의 중간 편집에서> 100 구성 방법)

이전 재귀 접근법 :

sub t{my$n=shift;if($n){--$n;for$R(0..$n){for$r(t($R)){for$l(t($n-$R)){push@_,"1$l$r"}}}}else{push@_,"0"}@_}print for t$_

재귀 ungolfed :

sub tree {
  my ($n) = @_;
  my @result = ();
  if ( $n ) {
    for $right_count ( 0 .. $n-1 ) {
      for $right ( tree( $right_count ) ) {
        for $left ( tree( ($n-1) - $right_count ) ) {
          push @result, "1$left$right";
        }
      }
    }
  }
  else {
    push @result, "0";
  }
  return @result;
}
foreach $tree ( tree($_) ) {
  print $tree;
}

2

PHP (142) (138) (134) (113)

"php golf.php 1"은 "100"을 출력합니다.

편집 : 다른 방법으로 4자를 잘라내어 $ n에서 되풀이하지 않고 0에서 문자열을 만듭니다. 단축 된 삼항 연산자에 PHP 5.3을 사용합니다. 그렇지 않으면 2 자 이상이 필요합니다.

편집 2 : 루프를 약간 변경하여 4 문자를 더 저장했습니다.

편집 3 : 다른 접근법을 시도하고 있었고 마침내 이전 방법 아래에 도달했습니다.

모든 트리는 4 ^ n (또는 n = 0 인 경우 0)과 2 * 4 ^ n 사이의 정수를 이진 표현으로 간주 할 수 있습니다. 이 함수는 해당 범위를 반복하여 각 숫자의 이진 문자열을 가져온 다음 "100"을 "0"으로 바꾸어 반복적으로 줄입니다. 마지막 문자열이 "0"이면 유효한 트리이므로 출력합니다.

for($i=$p=pow(4,$argv[1])-1;$i<=2*$p;){$s=$d=decbin($i++);while($o!=$s=str_replace(100,0,$o=$s));echo$s?:"$d\n";}

2

루비, 99 94 92 89 87 자

(n=4**gets.to_i).times{|i|s=(n+i-1).to_s 2;t=s*1;0while s.sub!'100',?0;puts t if s==?0}

입력은 stdin에서 읽습니다.

> echo 2 | ruby binary_trees.rb
10100
11000

편집 1 : 변경된 IO (Lowjacker의 의견 참조)

b=->n{n==0?[?0]:(k=[];n.times{|z|b[z].product(b[n-1-z]){|l|k<<=?1+l*''}};k)}
puts b[gets.to_i]

편집 2 : 변경된 알고리즘.

b=->n{n==0?[?0]:(k=[];b[n-1].map{|s|s.gsub(/0/){k<<=$`+'100'+$'}};k.uniq)}
puts b[gets.to_i]

편집 3 : 버전은 이제 세 번째 접근 방식을 취합니다 (migimaru의 아이디어 사용).

편집 4 : 다시 두 문자. migimaru에게 감사합니다.


stdin의 입력을 받아들이는 것이 한 글자 더 짧습니다.
Lowjacker

또한, 당신은 필요하지 않습니다 *?\n, 때문에 puts자신의 라인에 배열의 인쇄 각 요소를.
Lowjacker

@Lowjacker 감사합니다.
Howard

방금 Ruby를 배우려고 시도했지만 {} while 대신 0while을 사용하여 문자를 저장할 수 있다고 생각합니다. 적어도 NetBeans에서 작동합니다.
migimaru

또한 서브! gsub! 대신 여기에 충분하므로 다른 문자로 저장할 수 있습니다.
migimaru

1

루비 1.9 (80) (79)

DCharness에서 사용하는 비 재귀적이고 건설적인 접근 방식을 사용합니다.

편집 : 1 문자를 저장했습니다.

s=*?0;gets.to_i.times{s.map!{|x|x.gsub(?0).map{$`+'100'+$'}}.flatten!}
puts s&s

0

하스켈 122 자

main=do n<-readLn;mapM putStrLn$g n n
g 0 0=[['0']]
g u r|r<u||u<0=[]
g u r=do s<-[1,0];map((toEnum$s+48):)$g(u-s)(r-1+s)

IO는 haskell에서 코드의 중요한 부분이 아니기 때문에 다른 언어로 비슷한 솔루션을 사용할 수 있습니다. 대각선이 교차하는 경우 기본적으로 왼쪽 아래에서 오른쪽 위 사각형으로 무작위로 걷습니다. 다음과 같습니다.

module BinTreeEnum where

import Data.List
import Data.Monoid

data TStruct = NonEmpty | Empty deriving (Enum, Show)
type TreeDef = [TStruct]

printTStruct :: TStruct -> Char
printTStruct NonEmpty = '1'
printTStruct Empty = '0'

printTreeDef :: TreeDef -> String
printTreeDef = map printTStruct

enumBinTrees :: Int -> [TreeDef]
enumBinTrees n = enumBinTrees' n n where
  enumBinTrees' ups rights | rights < ups = mempty
  enumBinTrees' 0   rights = return (replicate (rights+1) Empty)
  enumBinTrees' ups rights = do
    step <- enumFrom (toEnum 0)
    let suffixes =
          case step of
            NonEmpty -> enumBinTrees' (ups - 1) rights
            Empty -> enumBinTrees' ups (rights - 1)
    suffix <- suffixes
    return (step:suffix)

mainExample = do
  print $ map printTreeDef $ enumBinTrees 4

나는 이것을 이것을 대답으로 받아 들일 의도는 없으며, 나는 거기에서 내 것을 던질 것이라고 생각했습니다.
Kyle Butt

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.