올바른 순서로 사탕을 먹는


36

사탕을 먹을 때 나는 평범한 평신도보다 더 높은 기준을 따릅니다. "혼합"과 "최종을 위해 최선을 다하는"사이에는 미묘한 균형이 있습니다.

이 도전에서, 당신은 각 문자가 사탕 조각을 나타내는 문자열을 받게됩니다. 다른 문자 (대소 문자 구분)는 다른 유형의 사탕을 나타냅니다. 그런 다음 프로그램은 아래 절차에 따라 올바른 사탕 소비 순서를 결정해야합니다. 이 작업을 수행하기 위해 완전한 프로그램 (STDIN / STDOUT) 또는 명명 된 함수를 작성할 수 있습니다.

내 사탕 보관함이라고 가정 해 봅시다 oroybgrbbyrorypoprr. 먼저, 사탕을 더 낮은 ASCII 문자 값을 타이 브레이커로 사용하여 사탕을 맨 위에 대량으로 같은 유형의 더미로 분류합니다.

rrrrrr
oooo
bbb
yyy
pp
g

그런 다음 사탕의 각 행을 가져 와서 간격을 따라 똑같이 간격을 둡니다. 예를 들어 사탕 3 개가있는 경우 1 개는 1/3, 2/3는 끝에 배치됩니다.

.r.r.r.r.r.r
..o..o..o..o
...b...b...b
...y...y...y
.....p.....p
...........g

그런 다음 각 열을 내려 가서 최종 캔디 주문을 만듭니다 rorbyroprbyorrobypg.

입력

캔디 숨김이 포함 된 문자열입니다. 위 예제의 입력은 다음과 같습니다.

oroybgrbbyrorypoprr

산출

사탕이 들어있는 끈은 올바른 소비 순서로 재구성되었습니다.

rorbyroprbyorrobypg

채점

이것은 코드 골프입니다. 바이트 단위의 최단 답변이 이깁니다. 표준 코드 골프 규칙이 적용됩니다.


사탕 수가 고르지 않은 경우 더 큰 공간을 추가합니까? 이 경우 r 캔디가 하나 더 있으면 격자 모양은 어떻습니까?
Vajura

38
마지막으로 사탕을 먹는 방법을 아는 사람.
Michael M.

12
그래서 ... 기본적으로 사탕 디더링.
COTO

9
이것은 실제로 사탕을 먹는 방법에 매우 가깝습니다. :)
Emil

3
한 사람이 얼마나 탐욕 스러울 수 있습니까? 먹을 사탕의 수에는 제한이 있습니까?
Alchymist

답변:


12

CJam, 78 68 61 45 42 39 31 30 바이트

l$:L{L\/,~}${:DM+:MD/,LD/,d/}$

STDIN을 통해 입력 문자열을 가져옵니다

재귀 접근 방식에서 영감을 얻었지만 약간 다릅니다. 조옮김이나 직사각형이 필요 없습니다!.

작동 방식 :

l$:L                              "Sort the input line and store it in L";
    {     }$                      "Sort the string based on this code block output";
     L\/,~                        "Sort based on number of occurrences of each";
                                  "character in the full string";
            {               }$    "Sort the sorted string again";
             :DM+:M               "Store each character in D, add to M and update M";
                   D/,            "Count occurrences of D in M";
                      LD/,        "Count occurrences of D in L";
                          d/      "Sort string based on the ratio of two occurrences";

(구문만큼 많은 부풀림이 필요하기 때문에 CJam은 더 이상 Pyth를 완성 할 수 없습니다)

여기 사용해보십시오


4
LCM이 필요하다고 생각하지 않습니다. 어떤 여러 작업을해야합니다. 이것은 당신이 대체 할 수 있도록해야 {_@_@{_@\%}h;/*}와 함께 :.
Dennis

<facepalm>은 그런 생각을하지 않았습니다.
옵티 마이저

길이 절반을 축하합니다!
isaacg

나는 다음과 같이 풍자적이라고 느낀다 : D
Optimizer

11

피스 , 25

shCoc/NhN/zhNm>o_/zZSzdUz

이 답변 에서 영감을 얻은 완전히 새로운 알고리즘을 사용합니다 .

(implicit)          z = input()
(implicit)          print
s                   combine list of strings into one string
 h                  first list in
  C                 matrix transpose of (e.g. first characters in first list, etc.)
   o                order_by(lambda N:
    c                        float_div(
     /NhN                              N.count(N[0]),
     /zhN                              z.count(N[0])),
    m                        map(lambda d:
     >                           slice_head(
      o                                     order_by(lambda Z:
       _/zZ                                          -1*z.count(Z),
       Sz                                            sorted(z)),
      d                                     d),
     Uz                          range(len(z))

단계별 :

  1. 먼저, 우리는 문자를 공통성, 알파벳순으로 분류하여 정렬했습니다. 이것은입니다 o_/zZSz. o파이썬과 동일하지만 sorted(<stuff>,key=<stuff>)키에 대한 람다 식은 문자열로 유지한다는 점을 제외하고.

  2. 그런 다음 길이 len(z)에서 길이 1 까지 해당 문자열의 접두사 목록을 생성합니다 . >python 's와 같습니다 <stuff>[<int>:].

  3. 그런 다음이 접두사 문자열 목록을 질문에 표시된 사각형 레이아웃의 접두사 첫 번째 문자에서 분수 위치 (0은 왼쪽 가장자리, 1은 오른쪽)로 재정렬합니다. /NhN접두사에서 첫 번째 문자가 접두사에서 몇 번 /zhN나오는지 계산하고 문자열에서 접두사에서 첫 번째 문자가 나타나는 횟수를 구멍으로 나타냅니다. 이렇게하면 그룹의 각 문자가 이끄는 각 접두사가 1/k해당 문자의 가장 오른쪽 k/k에있는 것부터 가장 왼쪽에있는 것 까지 다른 분수로 할당됩니다 . 접두사 목록을이 번호로 재정렬하면 레이아웃에서 적절한 위치를 제공합니다. 타이는 사전 순서를 사용하여 끊어지며, 원하는 순서대로 알파벳순으로 계산됩니다.

  4. 마지막으로 각 접두사 문자열에서 첫 번째 문자를 추출하여 단일 문자열로 결합하여 인쇄해야합니다. 첫 문자 추출은 hC입니다. C실제로 zip(*x)파이썬 3에서 목록에서 행렬 전치를 수행합니다 h. 결과 행렬의 첫 번째 행을 추출합니다. 1 문자 접두어가 있으면 다른 완전한 행이 형성되지 않으므로 실제로 이것은 유일한 행입니다. s이 튜플의 문자를 단일 문자열로 합산합니다. 인쇄는 암시 적입니다.

테스트:

$ pyth -c 'shCoc/NhN/zhNm>o_/zZSzdUz' <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

증분 프로그램 oroybgrbbyrorypoprr:

Sub-Piece                  Output

Sz                         bbbgoooopprrrrrryyy
o_/zNSz                    rrrrrroooobbbyyyppg      (uses N because o uses N on first use.)
m>o_/zNSzdUz               ['rrrrrroooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrroooobbbyyyppg', 'rrroooobbbyyyppg', 'rroooobbbyyyppg', 'roooobbbyyyppg', 'oooobbbyyyppg', 'ooobbbyyyppg', 'oobbbyyyppg', 'obbbyyyppg', 'bbbyyyppg', 'bbyyyppg', 'byyyppg', 'yyyppg', 'yyppg', 'yppg', 'ppg', 'pg', 'g']
oc/NhN/zhNm>o_/zZSzdUz     ['roooobbbyyyppg', 'obbbyyyppg', 'rroooobbbyyyppg', 'byyyppg', 'yppg', 'rrroooobbbyyyppg', 'oobbbyyyppg', 'pg', 'rrrroooobbbyyyppg', 'bbyyyppg', 'yyppg', 'ooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrrrroooobbbyyyppg', 'oooobbbyyyppg', 'bbbyyyppg', 'yyyppg', 'ppg', 'g']
Coc/NhN/zhNm>o_/zZSzdUz    [('r', 'o', 'r', 'b', 'y', 'r', 'o', 'p', 'r', 'b', 'y', 'o', 'r', 'r', 'o', 'b', 'y', 'p', 'g')]
shCoc/NhN/zhNm>o_/zZSzdUz  rorbyroprbyorrobypg

이전 답변 :

피스 , 34

ssCm*+t*u*G/zHS{-zd1]kd/zdo_/zNS{z

이 프로그램은 특정 하위 목록을 복제 할 횟수를 계산하여 작동합니다. 하위 목록은 다음과 같습니다 ['', '', '', '', ... , 'r']. 이 하위 목록의 총 길이는 다른 모든 사탕의 발생 횟수의 곱입니다 u*G/zHS{-zd1. 전체 하위 목록은 빈 문자열의 목록 ]k을 여러 번 복제 한 다음 요소를 제거하고 t끝에 사탕 이름을 추가하여 구성됩니다 +d.

그런 다음이 하위 목록은 사탕이 입력에서 발견되는 횟수만큼 복제되어 /zd각 사탕의 목록 길이가 동일합니다.

이제이 함수를 사용하여 고유 한 모든 사탕에 대해 올바른 정렬 순서 ( o_/zNS{z)로 매핑 하면 질문 문에있는 것과 비슷한 사각형이 있지만 마침표 대신 빈 문자열이 있습니다. 행렬 전치 ( C)와 두 개의 합산 ( ss)을 수행하면 최종 문자열이 제공됩니다.

확인:

$ pyth programs/candy.pyth <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

4
Pyth가 언어 구문 자체에서 암호화를 지원하는 것 같습니다!
Optimizer

@Optimizer 암호화? 무슨 소리 야?
isaacg

좋은! 아마도 for 루프를 맵으로 변경하려고 생각하지 않았을 것입니다. 훨씬 더 깨끗합니다.
FryAmTheEggman

소스 코드를보십시오. 암호화 된 메시지처럼 보입니다.
Optimizer

2
최신 알고리즘의 단계별 예제를 제공 할 수 있습니까? : 제발 :)
옵티 마이저

6

펄 5-62

61 코드 + 1 플래그

#!perl -n
print map/(.$)/,sort map/(.$)/*$_/$$1.~$_.$1,map++$$_.$_,/./g

먼저 입력을 문자 배열로 나눕니다 /./g.

변수의 수를 떠나 각 문자에 발생 인덱스를 추가 $a.. $zmap++$$_.$_. 이제 배열은 다음과 같습니다

1o
1r
2o
1y
1b
1g
2r
2b
3b
2y
3r
3o
4r
3y
1p
4o
2p
5r
6r

그런 다음 비율 $_/$$1, 카운트 타이 브레이커 ~$_및 ASCII 값 타이 브레이커로 연결된 정렬 키로 변환하십시오 $_. 결과가 명확 해집니다 (여기에 공백이 추가됨).

0.25 18446744073709551614 o
0.166666666666667 18446744073709551614 r
0.5 18446744073709551613 o
0.333333333333333 18446744073709551614 y
0.333333333333333 18446744073709551614 b
1 18446744073709551614 g
0.333333333333333 18446744073709551613 r
0.666666666666667 18446744073709551613 b
1 18446744073709551612 b
0.666666666666667 18446744073709551613 y
0.5 18446744073709551612 r
0.75 18446744073709551612 o
0.666666666666667 18446744073709551611 r
1 18446744073709551612 y
0.5 18446744073709551614 p
1 18446744073709551611 o
1 18446744073709551613 p
0.833333333333333 18446744073709551610 r
1 18446744073709551609 r

사전 식 (기본) 순서로 정렬 할 수 있습니다. 결국 마지막 문자를 추출하고 인쇄하십시오.print map/(.$)/


5

파이썬 3.x-124 바이트

C=input()
print("".join(s[1]for s in sorted(enumerate(C),key=lambda
t:((C[:t[0]].count(t[1])+1+1e-10)/C.count(t[1]),t[1]))))

이것은 사각형 방법보다 알고리즘이 훨씬 더 시원합니다!
isaacg

4

매쓰, 123 (119) 118 바이트

f=FromCharacterCode[s=SortBy;#&@@@s[Join@@(s[Tally@ToCharacterCode@#,-Last@#&]/.{x_,n_}:>({x,#/n}&~Array~n)),{Last}]]&

명명 된 함수를 정의합니다 f. 언 골프 드 :

f = FromCharacterCode[
   s = SortBy;
   # & @@@ s[
     Join @@ (
       s[
         Tally@ToCharacterCode@#,
         -Last@# &
         ] /. {x_, n_} :> ({x, #/n} &~Array~n)
       ),
     {Last}
     ]
   ] &

내장 합리적인 유형을 사용하는 것이 좋은 생각처럼 보입니다. 물론 이것은 CJam 근처에 없습니다. 기본적으로 도전 과제에 표시된 그리드를 쌍 목록으로 나타냅니다. 쌍의 첫 번째는 문자 코드이고 두 번째는 1보다 작거나 같은 분수의 위치입니다 (마지막 열은 1 임). 개별 문자가 올바른 순서로되어 있는지 확인한 후 원하는 결과를 얻기 위해 이것을 분수별로 안정적으로 정렬하면됩니다.


3

피스 45 47 48 51

이것은 또한 거의 확실하게 골프를 쳤다;)

Ko_/zNS{zFGK~Y]*+*t/u*GHm/zdK1/zG]k]G/zG)ssCY

각 내부 목록은 빈 문자열의 행과 사탕의 이름 인 목록 목록을 작성하여 작동합니다. 이 목록이 바뀌고 내부 목록이 결합 된 다음이 목록이 결합됩니다.

합계에 대해 알려주는 @isaacg에게 감사합니다!


2
s문자열 목록에서 다음과 같이 작동합니다 j"".
isaacg 2018

3

APL : 38

v⌷⍨⊂⍋⌽(n/-n),⍪∊+\¨n⍴¨÷n←{≢⍵}⌸v←{⍵[⍋⍵]}

설명:

v←{⍵[⍋⍵]}    orders input string
n←{≢⍵}⌸v     counts how many times each element appears in v
∊+\¨n⍴¨÷n     makes incremental sums in each letter "group" 
⍋⌽(n/-n),⍪   appends number of elements in letter group and orders the obtained matrix
v⌷⍨⊂         orders vector v with computed indices

tryapl.org에서 테스트 가능


2

R-166 자

library("plyr");s=function(a){l=table(strsplit(a,s="")[[1]]);l=ldply(l[order(-l,names(l))],function(n)data.frame(seq_len(n)/n));paste(l[order(l[[2]]),1],collapse="")}

ungolfed 버전

library("plyr")
s <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    tbl <- ldply(tbl, function(n) {data.frame(seq_len(n)/n)})
    paste(tbl[order(tbl[[2]]),1], collapse = "")
}

설명:

  • 개별 문자로 분할
  • 각 문자 수를 표로 작성하십시오
  • 표를 가장 빈번하게 정렬 한 다음 어휘 순서로 정렬
  • 1 / n, 2 / n, 3 / n, ... n-1 / n에서 선택을위한 인덱스 위치, 1 여기서 n은 사탕 수
  • 사탕 이름을 색인 order별로 정렬 (정렬에 안정적이므로 색인에 넥타이가있을 때 가장 자주 / 어휘 명명 순서를 유지합니다. 특히 마지막 사탕에서 중요합니다)
  • 캔디 이름을 연결하여 출력 문자열을 만듭니다.

문제의 매트릭스 특성으로 인해 R 이이 문제를 해결할 수 있다고 생각했지만 내가 할 수있는 알고리즘의 가장 문자 그대로 해석은 211 자였습니다.

l=function(a){l=table(strsplit(a,s="")[[1]]);l=l[order(-l,names(l))];o=Reduce(`*`,l);m=matrix("",nc=o,nr=length(l));for(r in seq_along(l)){x=l[r];for(c in seq_len(x)*o/x){m[r,c]<-names(x)}};paste(m,collapse="")}

언 골프 :

l <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    o <- Reduce(`*`, tbl)
    m <- matrix("", ncol = o, nrow = length(tbl))
    for (r in seq_along(tbl)) {
        for (c in seq_len(tbl[r])*o/tbl[r]) {
            m[r,c] <- names(tbl[r])
        }
    }
    paste(m, collapse="")
}

2

Pyth, 29 바이트

이것은 Pyth 에서 내 CJam answe r 의 직접 번역입니다

oc/|$Y.append(N)$YN/zNo_/zZSz

여기에서 온라인으로 사용해보십시오


이 솔루션에는 다소 긴 이야기가 있으며 @isaacg는이 새로운 언어를 이해하는 데 많은 도움이되었습니다.

이상적으로 이것은 CJam 코드 ( 17 바이트 ) 의 정확한 단어 대 단어 변환입니다 .

oc/~kNN/zNo_/zZSz

이는 다음을 의미합니다.

o         order_by(lambda N:
 c                 div(
  /                    count(
   ~kN                       k+=N,                #Update k (initially ""), add N
   N                         N),                  #Count N in updated k
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

그러나 슬프게도 Python은 +=호출 에서 아무것도 반환하지 않으므로 유효한 Python 코드가 아니므로 Pyth와 마찬가지로 잘못된 Pyth 코드도 반환 문이 될 수 있습니다.

그런 다음 다양한 방법을 살펴보고 마침내 파이썬이 사용할 수 list.append있는 None값을 반환한다는 것을 알았습니다. 코드를 ( 19 바이트 )로 만들기 :

oc/|aYNYN/zNo_/zZSz

이는 다음을 의미합니다.

o         order_by(lambda N:
 c                 div(
  /                    count(
   |aYN                      (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

그러나 슬프게도 a(추가)에 대한 지원은 Pyth에서 제거되었으며 지원하는 버전은 지원하지 않습니다 o.

업데이트 : a이제 Pyth에 지원이 추가되어 위의 19 바이트 코드가 온라인 컴파일러에서 작동합니다. 그러나 이것은 OP 후에 추가 된 새로운 기능이기 때문에 점수로 올리지 않고 29 바이트 코드를 솔루션으로 내버려두고 있습니다.

따라서이 경우 원시 Python에 의존하여 코드를

o         order_by(lambda N:
 c                 div(
  /                    count(
   |$Y.append(N)$            (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.