dc , 47 바이트
dc , 48 바이트
또한 Bash + Unix 유틸리티, 29 바이트
dc (47 바이트) :
1sb[_1sb]s zz?sdlb*sc[pld+lnx]sl[dlb*lcr<l]dsnx
온라인으로 사용해보십시오!
dc에서 숫자 입력을 허용하는 방식이므로 음수는 빼기 부호 대신 밑줄로 입력해야합니다. 예를 들어 -5 대신 _5를 쓰십시오.
dc는 문자 또는 문자열 입력을 변수로 읽어서 처리 할 수 없지만 (아래에 더 자세한 설명이 있음)이 문제를 해결하는 두 가지 방법을 찾았습니다.
47 바이트 DC 용액 인수 1을 가지며 구분자로 공백으로, 인수 2 반전 입력에 작동한다. 따라서 1에서 10까지 (3을 포함하지 않음)까지의 카운트는 다음과 같이 입력됩니다.
< 1 10 3
인수의 순서를 변경하는 것이 허용되지 않으면 인수 의 원래 순서를 유지 하는 48 바이트 dc 솔루션 도 제공합니다 . 이것은 zz인수 사이의 구분자로 사용 됩니다. 따라서 다시 3 단계로 1에서 10까지 세지 만 다음 입력 줄을 사용합니다.
1zz<zz10zz3
마지막으로, 동일한 아이디어는 29 바이트 bash 솔루션을 제공 합니다.
dc의 문자열 처리 부족에 대한 세부 사항 및이 프로그램이이를 처리하는 방법 :
dc는 대부분의 언어에서와 같이 문자열 또는 문자 입력을 허용하지 않기 때문에 dc에서이 문제를 처리하는 것은 까다 롭습니다. dc가 입력 문자열을 읽으면 해당 문자열을 즉시 dc 프로그램 (매크로)으로 실행 한 다음 해당 문자열을 버립니다. 문자열의 문자를 메모리에 저장하고 나중에 또는 다른 방식으로 처리 할 수 없습니다. 입력에 '<'또는 '>'가 있어야한다는 요구 사항을 방해합니다.
이것에 대해 두 가지 방법을 보여 드리겠습니다. 위의 솔루션 (47 바이트)에서 처음 두 입력의 순서를 전환합니다. 입력 분리 문자는 공백 문자입니다. 예를 들어, 1에서 10까지 (3을 포함하지 않음)까지 세려면 다음을 입력하십시오.
< 1 10 3
이 솔루션의 기본 개념은 다음과 같습니다.
dc의 매크로는 레지스터에 저장되며 레지스터는 단일 문자 이름을 갖습니다. 이름이 공백 문자 인 레지스터에 매크로를 저장합니다.
프로그램은 입력을 얻기 전에 스택에서 0과 1을 밀어서 작동합니다. 그런 다음 입력을 dc 프로그램 (입력 행으로 dc가 수행하는 작업)으로 실행하면 '<'또는 '>'문자가 명령으로 실행됩니다. 이는 이름이 매크로 인 조건부 매크로 실행입니다. '<'또는 '>'다음의 다음 문자 특히 스택의 상위 2 개 항목이 튀어 나옵니다. 첫 번째로 팝업 된 항목이 두 번째로 팝업 된 <(각각>)이면 표시된 매크로가 실행됩니다. 다음 문자 ( '<'또는 '>'뒤)는 공백이므로 레지스터에 이름이 공백 char 인 레지스터에 저장 한 매크로는 조건이 유지되는 경우 실행되는 매크로입니다. 그러나 스택에서 0과 1을 눌렀으므로 첫 번째 항목은 1이고 두 번째 항목은 0입니다. 결과적으로 매크로는 조건 테스트가 <가 아닌> 인 경우에만 실행됩니다. 이를 통해 입력에서 '<'와 '>'을 구별 할 수 있습니다.
행의 나머지 항목은 숫자 일 뿐이며 dc는 해당 숫자를 차례로 스택에 밀어 넣습니다.
자세한 설명은 다음과 같습니다. 대부분의 경우 계수 변수 (문제 설명의 의사 코드의 i)는 스택 맨 위에 저장됩니다.
1sb Store 1 in register b. (b will end up being 1 for '<', and -1 for '>').
[_1sb]s Note that there is a space after the second s. So the space char is the name of a macro which stores -1 in b.
z Push 0 on the stack.
z Push 1 on the stack.
? Accept input in the format above. This will:
- Store 1 or -1 in b, depending on whether you've typed "<" or ">"
- Push each of the three numbers in turn on the stack.
sd Save the increment in register d.
lb*sc Save either limit or -limit in register c, depending on whether the input started with "<" or ">".
[pld+lnx]sl Define a macro called l which is the body of our loop:
- Prints the top of the stack
- Adds the increment to the top of the stack.
- Calls macro n (the loop test).
[dlb*lcr<l]dsn Define a macro called n which is the test of the loop:
It checks to see if i (at the top of the stack) times b is less than c; if so, it calls macro l (looping back).
x Execute the loop test macro initially (a while loop needs to have a test at the top before entering the loop the first time).
반면 OP는 다음과 같이 말했습니다.
Input can be in one-line using any format "a/b/c/d" or "a,b,c,d" etc.
따라서 순서를 전환하는 것이 합법적이지 않고 입력에서 a 앞에 b가 필요합니다.
다음은 a, b, c 및 d를 원래 순서대로 유지하는 대안입니다. 구분자를 사용할 수 있습니다. zz를 구분 기호로 사용하겠습니다. 따라서 3 단계에서 1에서 10까지의 계산은 다음과 같이 입력됩니다.
1zz<zz10zz3
zz로 구분 된 입력을 가진 새로운 프로그램은
dc (48 바이트) :
1sb[_1sb]sz?sdiilb*sci[pld+lnx]sl[dlb*lcr<l]dsnx
이것은 47 바이트의 첫 번째 솔루션보다 1 바이트 더 깁니다.
온라인으로 zz로 구분 된 버전을 사용해보십시오!
개인적으로 다른 순서의 < 1 10 3형식이 문제의 정신에 1zz<zz10zz3더 가깝다고 생각하지만 실제 기술 사양을 더 잘 충족시킬 수 있습니다.
다른 입력 인수 사이에 다른 구분 기호를 허용하면 더 짧은 솔루션을 얻을 수 있지만 문제의 정신에 있다고 생각하지 않습니다.
Bash + Unix 유틸리티, 29 바이트
위의 기본 아이디어를 bash 프로그램 (dc를 호출)으로 바꿀 수 있습니다. 이렇게하면 "<"및 ">"의 모든 어려움을 피할 수 있으며 다양한 숫자 매개 변수 처리를 단순화하므로 @zeppelin의 bash + bc 답변과 동일하게 길이가 29 바이트에 불과합니다.
bash 버전 (29 바이트) :
dc -e[p$4+d$3r$2l]sl$1d$3r$2l
bash 버전을 온라인으로 사용해보십시오!
다음은 bash 프로그램 내부의 dc 프로그램 작동 방식에 대한 설명입니다.
i의 값은 대부분 스택의 맨 위에 저장됩니다.
[ Start of macro (i is at the top of the stack). This macro will be called l.
p Print i
$4+ i += (4th argument)
d Duplicate i at the top of the stack.
$3 Push the 3rd argument onto the stack.
r Swap the top two items on the stack, so i is at the top and arg3 is second
$2l $2 is "<" or ">", causing the top two items to be popped from the stack, and macro l is then called (effectively looping back) if i < arg3 or i > arg3, respectively.
]sl End of macro definition; store macro in register l.
$1 Push argument 1 onto the stack (i = 1st argument).
d$3r$2l Just as above, call macro l if i < arg3, or i > arg3, depending on whether arg2 is "<" or ">"