기능 클립 보드 : 복사


17

이 과제는 2018 년 5 월 Language of the Month 이벤트 일부로 일부 MATL 언어 기능과 관련이 있습니다 . 관련 도전 : 기능 클립 보드 : paste .


소개

MATL에는 여러 개의 클립 보드 가 있으며 , 여기에서 나중에 검색 (붙여 넣기) 할 값 (복사)을 저장할 수 있습니다. 일부 클립 보드는 자동 이므로 특정 이벤트에 의해 복사가 자동으로 시작됩니다. 이 과제는 함수 입력 클립 보드 또는 단순히 함수 클립 보드 라고하는 자동 클립 바 중 하나에 중점을 둡니다 .

이 클립 보드는 일반적인 입력 기능에 대한 최근 4 개의 호출에 대한 입력을 저장합니다. 정규 함수는 MATL에서 가장 일반적인 함수 유형입니다. 입력 은 기능이 최소한 하나의 입력 받는다는 것을 의미합니다 (입력을하지 않는 기능은 기능 클립 보드에서 고려하지 않음).

이것은 두 가지 일반 기능을 사용하는 다음 예제에서 가장 잘 설명됩니다.

  • +스택에서 두 숫자를 표시하고 합계를 푸시합니다.
  • U하나의 숫자가 나오고 제곱이됩니다.

예 1 :

3 2 + 6 + 12 4 U + +

결과를 생성 합니다 39. 코드는 다음과 같이 해석됩니다.

  • 같은 번호 리터럴 3또는 12스택에 푸시 얻을
  • +입력 을 팝하고 출력을 스택으로 푸시하는 등의 기능 .

시간순으로 함수 호출은 다음과 같습니다.

  1. 3 2 + 준다 5
  2. 5 6 + 준다 11
  3. 4 U 준다 16
  4. 12 16 + 28
  5. 11 28 +제공합니다 39.

클립 보드는 네 개의 목록으로 볼 수 있습니다. 각 내부 목록에는 함수 호출에 대한 입력이 포함되어 있으며 가장 최근 호출이 먼저 있습니다. 각 내부 목록 내에서 입력은 원래 순서대로되어 있습니다.

따라서 코드를 실행 한 후 클립 보드 내용은 (파이썬 표기법으로 표시됨)입니다.

[[11, 28], [12, 16], [4], [5, 6]]

예 2 :

10 20 U 30 +

숫자 10430스택에 나뭇잎 . 스택은 프로그램 끝에서 아래에서 위로 표시됩니다.

함수 호출은

  1. 20 U 준다 400
  2. 400 30 + 준다 430

두 개의 함수 호출 만 있었으므로 클립 보드를 정의하는 내부 목록 중 일부는 비어 있습니다. 10함수에 대한 입력으로 사용되지 않는 방법도 참고하십시오 .

따라서 코드를 실행 한 후 클립 보드 내용은 다음과 같습니다.

[[400, 30], [20], [], []]

예 3 (잘못된) :

10 20 + +

두 번째에 대한 입력이 없기 때문에 유효하지 않은 것으로 간주됩니다 +(MATL에서는 사용자 입력을 암시 적으로 트리거합니다).

도전

입력 : 문자열 S 번호 리터럴, +U공백으로 분리된다.

출력 : 문자열 평가 한 후 함수 클립 보드의 내용 S를 .

설명 :

  • 두 가지 일관된 기호를 사용하여 숫자 이외의 해당 기능을 나타낼 수 있습니다. 또한 공백 대신 일관된 기호를 구분 기호로 사용할 수 있습니다.
  • 표시된 두 기능 만 고려됩니다.
  • 입력 문자열에는 하나 이상의 숫자 리터럴과 하나 이상의 함수가 포함됩니다.
  • 모든 숫자는 양의 정수이며 두 자리 이상의 숫자 일 수 있습니다.
  • 예제 2에서와 같이 일부 숫자 리터럴은 어떤 함수에서도 사용되지 않을 수 있습니다.
  • 입력은 추가 번호없이 유효한 코드로 보장됩니다. 따라서 예제 3과 같은 문자열은 절대 발생하지 않습니다.
  • 출력에서 후행 빈 내부 목록을 생략 할 수 있습니다. 따라서 예제 2의 결과는[[400, 30], [20]]
  • 합리적이고 명확한 출력 형식이 허용됩니다. 예를 들어 내부 구분 기호로 쉼표를 사용하고 외부 구분 기호로 세미콜론을 사용하는 문자열 : 400,30;20;;.

추가 규칙 :

테스트 사례

Input
Output

3 2 + 6 + 12 4 U + +
[[11, 28], [12, 16], [4], [5, 6]]

15 3 4 + 2 U 8 + U +
[[7, 144], [12], [4, 8], [2]]

3 6 9 12 + + 10 8 U 6
[[8], [6, 21], [9, 12], []]

8 41 12 25 4 5 33 7 9 10 + + + + + + + +
[[41, 105], [12, 93], [25, 68], [4, 64]]

10 1 1 + U U U U U
[[65536], [256], [16], [4]]

[[28, 11], [16, 12], [4], [6, 5]]첫 번째 예를 들어 유효 출력은?
ovs

@ovs 아니오, 각 내부 목록 내의 입력은 원래 순서대로, 즉 함수 호출에서와 같이
Luis Mendo

흠, 우리는 MATL에서 이것을 해결하는 것을 권장하지 않습니까? : P
아웃 골퍼 Erik

1
이 클립 보드 M입니까?
주세페

1
@Giussepe 정확하게! 우리는 function을 사용하지 않기 때문에 여기에서 그 이름을 언급하지 않았습니다 M. 나는 "붙여 넣기"도전에서 그것을 할 것입니다
Luis Mendo

답변:



5

배쉬 , 43 바이트

sed s/+/rdnFPrp+/g\;s/U/p2^/g|dc|tac|sed 4q

온라인으로 사용해보십시오!

이렇게하면 클립 보드가 다음 형식으로 인쇄됩니다. \ x0F는 구분 기호로 사용됩니다.

item_1\x0Fitem_2
item_3
.
.
item_m\x0Fitem_n

핵심 아이디어는 이것을 스택 기반 언어 인 dc로 전달하여 필요한 스택 항목이 인쇄되도록하는 것입니다.

입력은 sed로 파이프되고 모든 +것이으로 대체됩니다 rdnFPrp+. dc에서는 스택의 두 번째 숫자와 \ x0F, 그리고 추가를 수행하기 전에 최상위 숫자가 인쇄됩니다. sed는 every U를 모두 로 바꾸고 p2^상단 스택 요소를 인쇄하고 사각형으로 만듭니다.

제 교체 명령 s에 의해 표시된 바와 같이, 모든 대체 g lobal 플래그 g, +s에서 rdnFPrp+. dc에서는 r맨 위 두 스택 항목을 교체하고 맨 위 항목을 d복제하고 n줄 바꿈없이 인쇄 한 다음 F15를 스택으로 푸시 P한 후 문자 (구분자)로 인쇄하고 r다시 스왑 p하고 맨 위 스택 항목을 인쇄 한 다음 +수행합니다. 상단 두 스택 항목에 추가.

우리는 또 다른 명령을 가지고 있으며, sed에서 명령은 세미콜론이나 줄 바꿈으로 구분되며 첫 번째 옵션이 선택됩니다. 단순히 ;bash가 sed 명령의 끝으로 해석하도록 만들면 a로 이스케이프됩니다 \.

마지막 대체 명령에서 U전역은로 대체됩니다 p2^. dc에서는 p인쇄 2^하여 두 번째 전력으로 올립니다.

sed의 결과는 dc 코드로 평가되어 전체 클립 보드를 인쇄합니다.

dc에 대한 파이프는 dc를 dc 코드로 해석합니다. 이제 가장 최근 통화는 맨 아래에 있고 이전 통화는 맨 위에 있습니다.

줄이 역순이므로 tac(reverse cat)를 사용하여 문제를 해결합니다.

그리고 마지막으로 sed는 tac에서 처음 4 줄을 선택합니다.

이것은 더 짧은 방법입니다 head -4. sed는 한 번에 하나씩 입력의 모든 행에 명령을 수행합니다. 명령이 없으면 입력에 아무런 작업도 수행되지 않고 그대로 리턴됩니다. sed가 라인 4 4q에서 명령을 수행하도록 지시합니다. sed가 q입력의 라인 4를 처리 할 때 처음 세 개의 입력이 이미 인쇄되었습니다. 이 명령 q은 프로그램을 종료하므로 네 번째 줄을 인쇄하고 종료 head -4합니다.



4

하스켈 , 113 109 바이트

take 4.([]#).words
x:y:s#"+":r=(x+y:s#r)++[[y,x]]
x:s#"U":r=(x*x:s#r)++[[x]]
s#n:r=read n:s#r
_#_=[]
infix 4#

첫 번째 줄은 문자열을 취하는 익명 함수를 정의하고, 예를 들어 "3 2 + 6 + 12 4 U + +"ints 목록을 반환합니다 [[11,28],[12,16],[4],[5,6]]. 온라인으로 사용해보십시오!


2

클린 , 140 바이트

import StdEnv,Text
k[a,b:n]["+":s]=k[a+b:n]s++[[b,a]]
k[a:n]["U":s]=k[a^2:n]s++[[a]]
k n[v:s]=k[toInt v:n]s
k _[]=[]
$s=k[](split" "s)%(0,3)

온라인으로 사용해보십시오!

고전적인 Clean 스타일에서는 약 50 % 더 긴 것을 제외하고 Haskell 솔루션입니다.


2

자바 스크립트 (ES6), 107 바이트

정수 이루어진리스트로의 입력을 받아, '+'그리고 'U'. 정수, 2 개의 정수 배열 및 '_'빈 슬롯 으로 구성된 다른 목록을 리턴 합니다.

a=>a.map(x=>s.push(+x?x:(c=[x>[a=s.pop(),r=a*a]?a:[r=s.pop(),(r+=a,a)],...c],r)),s=[c='___'])&&c.slice(0,4)

온라인으로 사용해보십시오!

댓글

a =>                          // a[] = input array
  a.map(x =>                  // for each entry x in a[]:
    s.push(                   //   update the stack:
      +x ?                    //     if x is a positive integer:
        x                     //       push x onto the stack
      :                       //     else:
        ( c = [               //       update the clipboard:
            x > [             //         compare x with '['
              a = s.pop(),    //         a = first operand
              r = a * a       //         use a² as the default result
            ] ?               //         if x is 'U' (greater than '['):
              a               //           save the 1st operand in the clipboard
            :                 //         else:
              [ r = s.pop(),  //           r = 2nd operand
                (r += a, a)   //           add the 1st operand
              ],              //           save both operands in the clipboard
            ...c              //         append the previous clipboard entries
          ],                  //       end of clipboard update
          r                   //       push r onto the stack
        )                     //
    ),                        //     end of stack update
    s = [c = '___']           //   initialize the stack; start with c = '___'
  ) &&                        // end of map()
  c.slice(0, 4)               // return the last 4 entries of the clipboard

2

이동, (305) 303 295 바이트

@ovs 덕분에 8 바이트가 떨어 졌습니다.

func e(s string){b,v,w,x,r:=[][]int{{},{},{},{}},[]int{},0,0,0;for _,d:=range Split(s," "){if d=="+"{w,x,v=v[0],v[1],v[2:];r=w+x;b=append([][]int{[]int{x,w}},b...)}else if d=="U"{w,v=v[0],v[1:];r=w*w;b=append([][]int{[]int{w}},b...)}else{n,_:=Atoi(d);r=n};v=append([]int{r},v...)};Print(b[0:4])}

온라인으로 사용해보십시오!


2

옥타브 , 206 바이트

s=strsplit(input(''));m=t=[];for z=s
if(q=str2num(p=z{1}))t=[t q];else
if(p-43)m{end+1}=(k=t(end));t(end)=k^2;else
m{end+1}=(k=t(end-1:end));t(end-1:end)=[];t(end+1)=sum(k);end
end
end
m(1:end-4)=[];flip(m)

온라인으로 사용해보십시오!

옥타브 만이 pop구문을 가지고 있다면 . m메모리 클립 보드, t스택입니다.


끝이 아닌 앞면에 요소를 추가하여 구성 m하고 t반대로 할 수 있습니까?
주세페

위에서 설명한 전략을 사용하는 178 바이트
Giuseppe

@Guiseppe Clever. 나는 항상 추가하는 것이 일반적으로 앞에
붙는


1

빨강 , 335330 바이트

func[s][b: copy[]foreach c split s" "[append b either c >"+"and(c <"U")[do c][c]]r: copy[]until[t: 0 until[not parse
b[to copy c[2 integer!"+"](insert/only r reduce[c/1 c/2]replace b c c/1 + c/2 t: 1)to end]]until[not parse b[to copy
c[integer!"U"](insert/only r to-block c/1 replace b c c/1 ** 2 t: 1)to end]]t = 0]take/part r 4]

온라인으로 사용해보십시오!

더 읽기 쉬운 :

f: func[s] [
    s: split s " "
    b: copy []
    foreach c s [
        append b either (c > "+") and (c < "U")[do c] [c]
    ]
    r: copy []
    until [
        t: 0
        until [
            not parse b [to copy c[2 integer! "+"]
            (insert/only r reduce[c/1 c/2]
            replace b c c/1 + c/2
            t: 1)
            to end]
        ]
        until [
            not parse b [to copy c[integer! "U"]
            (insert/only r to-block c/1
            replace b c c/1 ** 2
            t: 1)
            to end]
        ]
        t = 0
    ]
    take/part r 4  
]

1

R , 205 182 바이트

function(P){S=F
M=list()
for(K in el(strsplit(P," "))){if(is.na(x<-strtoi(K))){if(K>1){M=c(m<-S[1],M)
S[1]=m^2}else{M=c(list(m<-S[2:1]),M)
S=c(sum(m),S[-2:0])}}else S=c(x,S)}
M[1:4]}

온라인으로 사용해보십시오!

M메모리 클립 보드, P프로그램 및 S스택입니다.

기술적 S으로 단일 0을 포함하는 벡터로 초기화되지만 유효하지 않은 입력을 얻지 않기 때문에에서 바이트를 저장합니다 S={}.


1

C (gcc) , 264 바이트

함수 스택을 데이터 스택으로 사용할 수 있도록 재귀를 사용했습니다. 입력 목록이 안내되고 작업이 수행됩니다. 결과는 스택 푸시가 표시되지 않은 상태로 역순으로 표시됩니다.

스택은 연결된 목록으로 구현됩니다. 작동 방식은 다음과 같습니다.

  • 현재 노드는 [포인터 값, 포인터 이전 노드]로 설정됩니다.
  • 값을 푸시하기 위해 값이 저장되고 현재 노드에서 함수가 다시 호출됩니다.
  • 값을 팝하거나 스택의 맨 위에있는 값을 수정하기 위해 이전 노드의 값이 수정되고 이전 노드에서 함수가 다시 호출됩니다.

원래 노드에 구조를 사용했지만 공간을 절약하기 위해 베어 포인터로 전환했습니다. 이 연결리스트의 흥미로운 특징은 재귀가 완료되면 스스로 정리된다는 것입니다.

#define _ printf
f(char**s,int**p){int**w,v,*y[]={&v,p},m,n,t,z;w=y;z=1;return(*s?(**s-85?**s-43?(--z,t=14,v=atoi(*s)):(t=6,w=p[1],m=**w,**w+=n=**p):(t=0,w=p,**w*=m=**p),v=f(s+1,w),_(v<4?",[%d]\0,[%d,%d]\0"+t+!v:"",m,n),v+z):0);}g(char**s){_("[");f(s,0);_("]\n");}

온라인으로 사용해보십시오!

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