22
\$\begingroup\$

Try to create a simple ASCII art scissors animation!

Challenge

All inputs will be integers -31 through 31.

The output will be an animation (To be outputted somewhere, as long as the previous frame is replaced. GIFs are allowed.), separated by (approximately) 1 quarter of a second.

If the input (n) is positive:

  • The animation should start with 8<, AKA open scissors.
  • The next frame is 8=. This shows the scissors "cutting".
  • A dash (cut mark) is added behind the scissors, and the animation repeats until there are n dashes.

If the input is negative:

  • The scissors start open and facing towards the left (Like this: >8), with n spaces in front of it.
  • The scissors close and remain facing towards the left (=8).
  • The scissors re-open, as space is removed, and a dash is added behind the scissors.

If the input is zero:

  • Output just the scissors opening and closing, for 10 frames. They can be facing either direction, as long as it is consistent.

This is , so the shortest submission in bytes wins. (Even if your entry clearly won't win because of some sort of newfangled "golfing language", we'd still like to see it.)

Error messages are allowed, as long as the error message itself does not interfere with the animation.

Example Input and Output Pairs:

(I separated the frames for clarity, but there should be approximately .25 seconds between each frame)

Input: 1
Output: 
8<
8=
-8<

Input: 2
Output:
8<
8=
-8<
-8=
--8<

Input: 5
Output:
8<
8=
-8<
-8=
--8<
--8=
---8<
---8=
----8<
----8=
-----8<

Input: 0
Output:
8<
8=
8<
8=
8<
8=
8<
8=
8<
8=

Input: -2
Output:
  >8
  =8
 >8-
 =8-
>8--

Input: -3
Output:
   >8
   =8
  >8-
  =8-
 >8--
 =8--
>8---

Enjoy!

\$\endgroup\$
3
  • \$\begingroup\$ Yes, it is. I will add that. \$\endgroup\$
    – iPhoenix
    Commented Jan 25, 2018 at 21:33
  • \$\begingroup\$ Does the font need to be monospaced? \$\endgroup\$
    – Οurous
    Commented Jan 25, 2018 at 21:38
  • \$\begingroup\$ @Οurous If your language supports it, yes. Otherwise, no. \$\endgroup\$
    – iPhoenix
    Commented Jan 25, 2018 at 21:43

10 Answers 10

5
\$\begingroup\$

SOGL V0.12, 53 bytes

LA0≠?.θ«IA}a∫H.¡*»:B┌* 8+Ƨ<=F2%W+a»b-@*+.0<?↔±}1¼UU░P

Try it Here!

\$\endgroup\$
5
\$\begingroup\$

MATL, 59 58 57 bytes

|EQG~10*+:"&FXx45@q2/kGg*XHY"8Vh61@oGO<Eq*+h4M?G|H-Z"hP]D

Try it at MATL Online! Or see an example run from the offline compiler:

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ It might just be me, but it appears that the closed scissor animations are longer than the open scissor ones. Is this just due to the processing of the language? \$\endgroup\$
    – iPhoenix
    Commented Jan 26, 2018 at 0:01
  • 1
    \$\begingroup\$ I haven't noticed that, but it could be. What I notice is, the leftward ones are a bit slower; and that makes sense because they have some more processing. Anyway, just to be sure, since the challenge says separated by (approximately) 1 quarter of a second I guess it's acceptable, right? \$\endgroup\$
    – Luis Mendo
    Commented Jan 26, 2018 at 0:39
  • \$\begingroup\$ I found someone who knew MATL, and they showed my what your code was doing, and it seems fine :) \$\endgroup\$
    – iPhoenix
    Commented Jan 26, 2018 at 1:55
  • \$\begingroup\$ @iPhoenix I should have added an explanation:-) \$\endgroup\$
    – Luis Mendo
    Commented Jan 26, 2018 at 11:03
4
\$\begingroup\$

JavaScript (ES2017) + HTML, 165 + 10 bytes

-16 bytes by @Shaggy

n=>(g=i=>i<-~(n?2*m:9)&&setTimeout(g,250,i+1,s=8+"<>="[i%2?2:n<0|0],o=("-".repeat(i/2)+s).padEnd(m+2),e.innerHTML=(n?n<0?[...o].reverse().join``:o:s)))(0,m=n<0?-n:n)
<pre id=e>

Try it in the below snippet:

let globalTimeout;
const _setTimeout = setTimeout;
window.setTimeout = function(){ globalTimeout = _setTimeout.apply(this, arguments); }
// Code above is to support user input

f=
n=>(g=i=>i<-~(n?2*m:9)&&setTimeout(g,250,i+1,s=8+"<>="[i%2?2:n<0|0],o=("-".repeat(i/2)+s).padEnd(m+2),e.textContent=(n?n<0?[...o].reverse().join``:o:s)))(0,m=n<0?-n:n)

// Code below is to support user input
f(10)
const $inp = document.getElementById("inp");
inp.addEventListener("change", ()=>{
  clearTimeout(globalTimeout);
  f(+inp.value);
});
<input type="number" id="inp" min="-31" max="31" value="10" />

<pre id=e>

\$\endgroup\$
2
  • 1
    \$\begingroup\$ A few quick savings to get you down to 157 bytes using just JS. (Although alerting each "frame" might not adhere to the spec, you may want to get clarification on that.) \$\endgroup\$
    – Shaggy
    Commented Jan 26, 2018 at 15:27
  • \$\begingroup\$ @Shaggy Thanks for the improvements! I intentionally didn't use alert since the requirements are that the frames come at ~0.25s intervals, which alert wouldn't support without further user input. \$\endgroup\$
    – Birjolaxew
    Commented Jan 26, 2018 at 21:25
2
\$\begingroup\$

TI-BASIC, 173 bytes

:"-
:For(X,1,5
:Ans+Ans
:End
:For(X,1,32
:" "+Ans+" →Str1
:End
:ClrHome
:Input N
:N<0→X
:For(A,not(N),abs(N+5not(N
:For(B,4-3X,6-3X-(A=abs(N)),2
:33X-Anot(not(N
:Output(1,16,sub(Str1,33X+32,abs(Ans-1)-NX-31X)+sub(">8=8<8=",B,2)+sub(Str1,Ans+32,1
:rand(11
:End
:End

Having the 0 input terminate in a different frame from the others was a very interesting obstacle!

Since TI-BASIC doesn't like empty strings, this maintains at least one dummy character to the left of the scissors, the first of which is constantly a space; to hopefully avoid counting this as part of the n spaces for negative inputs, this program begins printing from the rightmost column of the first row, then wraps the remainder of the string downward in order to begin the actual field of animation there, fresh off the first column.

Some notes for an exotic device: TI-BASIC code size is measured in tokens, not characters. For consistent cross-calculator comparisons, we usually ignore byte counts dealing with header lengths (e.g., we subtract 8 from PROGRAM:SCISSORS). Additionally, for routines which are fully well-behaved on the home screen (those lacking in control structures, for the most part), we further eliminate the size of an empty program to "save" on 9 bytes as well. This program in particular is not typable on the home screen, so that liberty won't be taken.

\$\endgroup\$
1
  • \$\begingroup\$ I tried this challenge in TI-BASIC (In study hall, on my CE. Where else?) when I thought of it, and my program was at least twice as large as this. Well done. \$\endgroup\$
    – iPhoenix
    Commented Jan 27, 2018 at 20:37
2
\$\begingroup\$

Octave, 190 186 bytes

k=32+~e((a=abs(n=(z=input(''))+~z*10))+1,1);for i=1:a
clc
k(i:i+1)=[56,61-(s=sign(n))];q=@(m)fprintf(rot90([m ''],s));q(k)
if(i-a)pause(.25)
clc
k(i+1)+=s;q(k)
pause(.25);k(i)=45;end
end

Try it online! (note: clc does not work in TIO, so it's just all the animation frames outputted sequentially). Thanks for @LuisMendo for making me aware of the function e(...) in Octave, which is equal to exp(1)*ones(...).

It turns out that inline assignments return only the changed array entries, not the entire array. This means that constructions like q(k(i+1)+=s) are not possible, so the program is almost like MATLAB. In fact, the MATLAB entry is only slightly longer,

MATLAB, 198 195 bytes

n=input('');n=n+~n*10;a=abs(n);s=sign(n);k=zeros(a+1,1);q=@(k)fprintf(rot90([k ''],s));for i=1:a
k(i:i+1)=[56 61-s];clc
q(k)
if(i-a)pause(.25);
k(i+1)=k(i+1)+s;clc
q(k)
pause(.25)
k(i)=45;end
end
\$\endgroup\$
3
  • \$\begingroup\$ In Octave, I think you can replace +ones by the uglier +~e. Also, in Octave and in Matlab, replace [i i+1] by i:i+1. \$\endgroup\$
    – Luis Mendo
    Commented Jan 27, 2018 at 20:10
  • \$\begingroup\$ @LuisMendo What on Earth is the use of e(...) like that? I don't think I've ever felt the need for an m-by-n matrix of e. Makes for good golfing though. \$\endgroup\$
    – Sanchises
    Commented Jan 28, 2018 at 9:47
  • \$\begingroup\$ Perhaps the Octave developers had code golf in mind, haha \$\endgroup\$
    – Luis Mendo
    Commented Jan 28, 2018 at 14:09
2
\$\begingroup\$

PowerShell, 281 bytes

$n=$args[0];$o="8<";$c="8=";function x{sleep .25};if($n-le0){$n=[math]::abs($n);$o=">8";$c="=8";$p=' '*$n;$p+$o;$x;$p+$c;1..$n|%{$p=$p-replace"\s$","";$p+$o+('-'*$_);if($_-eq$n){break};$x;$p+$c+('-'*$_)};$x}else{$o;x;$c;1..$n|%{
$y='-'*$_;$y+"8<";if($n-eq$_){break};$x;$y+"8=";$x}}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Clean, 294 bytes

import StdEnv,System.Time,ArgEnv,System._Unsafe
Start#n=toInt(select(getCommandLine)1)
=[?k l\\k<-[1..]&l<-if(n==0)(flatten o$5)(init)[$(abs n+2)'\b'++if(n<0)(rjustify(abs n+2))reverse[c,'8': $i'-']\\i<-[0..abs n],c<-[if(n<0)'>''<','=']]]
?t#(Clock n)=accUnsafe clock
|n>t*250=id= ?t
$ =repeatn

Try it online!

Note that this doesn't work on TIO, the link is just for presentation purposes.

Your results may vary if you have a CLOCK_PER_TICK constant other than 1000, the default for x86 Windows Clean.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 170 bytes

import time
n=input()
a=abs(n);s=a and n/a
for i in range([a-~a,10][a<1]):print'\n'*30+(a-i/2)*-s*' '+i/2*s*'-'+'>='[i%2]*(s<1)+'8'+'<='[i%2]*s+i/2*-s*'-';time.sleep(.25)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ (approximately) 1 quarter of a second; why not use a sleep time of .2 seconds and save a byte? \$\endgroup\$ Commented Jan 28, 2018 at 1:30
1
\$\begingroup\$

Ruby, 169 bytes

->x{i="";o=?=;(x!=0&&x.abs*2+1||10).times{|l|o=o[?=]?x>0?"8<":">8":x>0?"8=":"=8";f=?\s*(x<0&&-x-l/2||0);system"cls";puts x>0?i+o:f+o+i;i+=?-if(l).odd?&&x!=0;sleep 0.25}}

Pretty much self explainatory when you dig into it, atleast in my opinion. Program has to be running on a computer with the cls command/alias.

Try it online! ( Had to overwrite the system() method, just for this script, due to the limitations mentioned above. )

I did try to use

puts `cls`, ...

But it just printed an invisible character, anyone know why?

\$\endgroup\$
1
\$\begingroup\$

Stax, 46 41 bytes

üîφL↑≥ª⌡↨ÄA ¡`╢Σ·TmÄ↕=≈─Xí♫αF²M☻8]▒2±(═[3

Run and debug it

|, was included in a recent release, which is great for this challenge!

Uses JS requestAnimationFrame for pausing between snips.

Each testcase happens continuously after the other, so if you want a more clear version, try this!.

-5 bytes from recursive. (:R)

Explanation

c|a^5?rFxs0?.<={n'-*'8+s+x|a^^(x0<{:R}M{|,}9*|:pF

c|a^5? initial zero check:

? if the input is truthy

|a^ take abs(n) and increment

5 otherwise push 5

r range 0..n-1

F for each value in the range,

xs0? r: if input is 0, then push 0, otherwise push loop iteration no.

.<={...Ffor each value in "<=",

n'_* repeat "_" r times

'8+ add 8 to that

s+ add current loop iteration to that

x|a^^ take abs(input) and increment twice

( pad on right to that length

x0<{...}M if input is less than 0

:R reflect the string (<>)

{|,}9* delay 9 frames

|: output a form feed (clear screen)

p print the string without newline

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.