Create a scissors animation!

21

2

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!

iPhoenix

Posted 2018-01-25T21:16:20.800

Reputation: 592

Yes, it is. I will add that. – iPhoenix – 2018-01-25T21:33:53.497

Does the font need to be monospaced? – Οurous – 2018-01-25T21:38:24.867

@Οurous If your language supports it, yes. Otherwise, no. – iPhoenix – 2018-01-25T21:43:32.440

Answers

5

SOGL V0.12, 53 bytes

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

Try it Here!

dzaima

Posted 2018-01-25T21:16:20.800

Reputation: 19 048

5

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

Luis Mendo

Posted 2018-01-25T21:16:20.800

Reputation: 87 464

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? – iPhoenix – 2018-01-26T00:01:12.573

1I 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? – Luis Mendo – 2018-01-26T00:39:13.600

I found someone who knew MATL, and they showed my what your code was doing, and it seems fine :) – iPhoenix – 2018-01-26T01:55:24.097

@iPhoenix I should have added an explanation:-) – Luis Mendo – 2018-01-26T11:03:40.883

4

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>

Birjolaxew

Posted 2018-01-25T21:16:20.800

Reputation: 323

1

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.)

– Shaggy – 2018-01-26T15:27:22.610

@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. – Birjolaxew – 2018-01-26T21:25:30.623

2

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

Sanchises

Posted 2018-01-25T21:16:20.800

Reputation: 8 530

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. – Luis Mendo – 2018-01-27T20:10:22.233

@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. – Sanchises – 2018-01-28T09:47:21.220

Perhaps the Octave developers had code golf in mind, haha – Luis Mendo – 2018-01-28T14:09:18.427

2

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.

Weregoose

Posted 2018-01-25T21:16:20.800

Reputation: 81

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. – iPhoenix – 2018-01-27T20:37:41.763

1

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.

Οurous

Posted 2018-01-25T21:16:20.800

Reputation: 7 916

0

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!

ovs

Posted 2018-01-25T21:16:20.800

Reputation: 21 408

(approximately) 1 quarter of a second; why not use a sleep time of .2 seconds and save a byte? – Jonathan Frech – 2018-01-28T01:30:08.633

0

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?

Håvard Nygård

Posted 2018-01-25T21:16:20.800

Reputation: 341