Discuss Scratch

MegaApuTurkUltra
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

liam48D wrote:

Hey, maybe I'll just make a list everybody can use.

Oh wait..




I've made an attempt to compile all the workarounds though

$(".box-head")[0].textContent = "committing AT crimes since $whenever"
-Io-
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

liam48D wrote:

Hey, maybe I'll just make a list everybody can use.

Oh wait..


That's what happens with pretty much every userscript idea/request on the ATs too :p

theonlygusti
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

MegaApuTurkUltra wrote:

theonlygusti wrote:

MegaApuTurkUltra wrote:

PullJosh wrote:

Firedrake969 wrote:

Something along the lines of “if b is 0, return 0, else return a/(1/b)” would work for multiplication I guess
(<<(b) = [0]> = <[1] = [0]>> * ((a) / ((1) / (b))))
Ok, added

I love your sig :P

So far, 67 out of 145 blocks are eliminated. Almost 50%!
I eliminated 86; why is there such a large discrepancy between our answers?
Pls explain the workarounds you have?
Okay, I am making a project for them now.

joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

theonlygusti wrote:

MegaApuTurkUltra wrote:

Let me try to precisely define “Fewest amount of blocks technically needed to use Scratch”
Fewest amount of blocks needed to exactly replicate the functionality of any normal Scratch project

In that case
...
(days since 2000)
(username)
(() + ())
(() * ())
(() / ())
(pick random () to ())
<[] < [ ]>
<[] = [ ]>
(join [] [world])
(letter () of [world])
(length of [])
([ v] of ()::operators)
...
There are probably still more that can be snipped out of this
Yeah, you don't need anywhere near that many…. let's start with operators:

((a) * (b))

([10^ v] of (([log v] of (a)) + ([log v] of (b)))::operators)

((a) / (b))

([10^ v] of (([log v] of (a)) + ([10^ v] of (([log v] of (-1)) + ([log v] of (b)))::operators))::operators)

The log of -1 is a complex number (specifically i*pi/ln(10), which scratch does not support. You could implement a complex number system, but that would require the aforementioned blocks.



And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
theonlygusti
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

theonlygusti wrote:

MegaApuTurkUltra wrote:

Let me try to precisely define “Fewest amount of blocks technically needed to use Scratch”
Fewest amount of blocks needed to exactly replicate the functionality of any normal Scratch project

In that case
...
(days since 2000)
(username)
(() + ())
(() * ())
(() / ())
(pick random () to ())
<[] < [ ]>
<[] = [ ]>
(join [] [world])
(letter () of [world])
(length of [])
([ v] of ()::operators)
...
There are probably still more that can be snipped out of this
Yeah, you don't need anywhere near that many…. let's start with operators:

((a) * (b))

([10^ v] of (([log v] of (a)) + ([log v] of (b)))::operators)

((a) / (b))

([10^ v] of (([log v] of (a)) + ([10^ v] of (([log v] of (-1)) + ([log v] of (b)))::operators))::operators)

The log of -1 is a complex number (specifically i*pi/ln(10), which scratch does not support. You could implement a complex number system, but that would require the aforementioned blocks.

You are correct. I think I mistyped my scratchblocks, because I had a method that worked somewhere else. However, the method I posted above doesn't work anyway due to rounding errors.

joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

Let's tackle the
([ v] of (9) :: operators)
block using one of my favourite areas of mathematics, Taylor Series:

(not tested, also may be inefficient)

define e^ (x) // e^x = 1 + x + x^2/2! + x^3/3! + x^4/4!+ ... + x^n / n!
set [n v] to [0]
set [result v] to [0]
set [previous result v] to [-1] // Just has to be anything besides 0 - we're using it to track the accuracy
set [term v] to [1] // the nth term = x^n/n!, which will be equal to (previous term) * x / n (with 0-based indexing - i.e. the 0th term is 1, the 1st term is x/1!, etc)
repeat until <(previous result) = (result)> // When this happens we can't gain any more accuracy
set [previous result v] to (result)
change [result v] by (term)
change [n v] by (1)
set [term v] to (((term) * (x)) / (n))
end

define 10^ (x)
e^ ((x) * (2.30258509299404568401799)) // = ln(10) - http://www.wolframalpha.com/input/?i=ln+10

define sin (x) in radians // sin(x) = x - x^3/3! + x^5/5! + ... + (-1)^(2n+1) * x^(2n+1) / (2n+1)!
set [2n+1 v] to [1]
set [result v] to [0]
set [previous result v] to [-1]
set [term v] to (x) // the nth term equal to (previous term) * -x^2 / (2n) / 2n+1
repeat until <(previous result) = (result)>
set [previous result v] to (result)
change [result v] by (term)
change [2n+1 v] by (2)
set [term v] to ((0) - (((((term) * (x)) * (x)) / ((2n+1) - (1))) / (2n+1))
end

define sin (x) in degrees
sin (((x) / (180)) * (3.14159265353589793)) in radians // 1 degree = pi/180 radians

define cos (x) in radians // cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ... + (-1)^n * x^2n / (2n)!
set [2n v] to [0]
set [result v] to [1]
set [previous result v] to [-1]
set [term v] to [1] // the nth term, equal to (previous term) * - x^2 / (2n-1) / (2n)
repeat until <(previous result) = (result)>
set [previous result v] to (result)
change [result v] by (term)
change [2n v] by (2)
set [term v] to ((0) - (((((term) * (x)) * (x)) / ((2n) - (1))) / (2n))
end

define cos (x) in degrees
cos (((x) / (180)) * (3.14159265353589793)) in radians

define tan (x) in degrees // tan(x) = sin(x) / cos(x) Don't need radians because scratch doesn't use them. The definition would be exactly the same except with radians.
sin (x) in degrees
set [temp v] to (result)
cos (x) in degrees
set [result v] to ((temp) / (result)) // It is possible to rewrite sine and cosine to share a single loop, making this, and the inverse trig functions later, more efficient

// For the rest, they're inverse functions:
// let's use the Newton Raphson method: https://en.wikipedia.org/wiki/Newton's_method
// Taylor series exist, but for ln it only works when x <= 2,
// and the others are really complicated (some even have complex numbers!),
// and I don't know their convergence conditions
// We need some calculus - for f(x) = 0, for an initial approximation x_0,
// x_n+1 = x_n - f(x_n)/f'(x_n) where f'(x) = d f(x) / dx
// x_n will then be a sequence of successively better approximations.

define sqrt (y) // using y as not to confuse it with the x's in the definition
if <(y) < (0)>
say [Error - Input to sqrt out of range] // Well, complex numbers are a thing, but scratch doesn't have them so we don't need them either
stop [all v]
end
set [result v] to [1] // takes the role of x_0 to x_n
set [previous result v] to [0]
repeat until <(previous result) = (result)>
set [previous result v] to (result)
set [result v] to (((result) + ((y) / (result))) / (2)) // x^2 - y = 0 => x_n+1 = x_n - ((x_n)^2 - y)/ 2(x_n) = (x_n + y/x_n) / 2
end

define ln (y)
if <not <(y) > (0)>>
say [Error - Input to ln out of range]
stop [all v]
end
set [result2 v] to [1] // e^x uses result, so we need a different variable. Alternatively, use a stack.
set [previous result2 v] to [0]
repeat until <(previous result2) = (result2)>
set [previous result2 v] to (result2)
// e^x - y = 0 => x_n+1 = x_n - (e^(x_n) - y) / e^(x_n)) = x_n - 1 + y*e^(-x_n)
e^ ((0) - (result2))
change [result2 v] by (((y) * (result)) - (1))
end
set [result v] to (result2)

define log (y)
ln (y)
set [result v] to ((result) / (2.30258509299404568401799))

define convert result to degrees
set [result v] to (((result) * (180)) / (3.14159265353589793))

define arcsin (y) in radians // can't remember if scratch says arcsin or asin or sin^-1
if <<(y) < (-1)> or <(y) > (1)>
say [Error - Input to arcsin out of range]
stop [all v]
end
set [result2 v] to [1]
set [previous result2 v] to [0]
repeat until <(previous result2) = (result2)>
set [previous result2 v] to (result2)
// sin(x) - y = 0 => x_n+1 = x_n - (sin(x_n) - y / cos(x_n))
sin (result2) in radians
set [temp v] to (result)
cos (result2) in radians
change [result2 v] by (((y) - (temp)) / (result)
end
set [result v] to (result2)

define arcsin (y) in degrees
arcsin (y) in radians
convert result to degrees


define arccos (y) in radians
if <<(y) < (-1)> or <(y) > (1)>
say [Error - Input to arccos out of range]
stop [all v]
end
set [result2 v] to [1]
set [previous result2 v] to [0]
repeat until <(previous result2) = (result2)>
set [previous result2 v] to (result2)
// cos(x) - y = 0 => x_n+1 = x_n - (cos(x_n) - y / -sin(x_n)) = x_n + (cos(x_n) - y) / sin (x_n)
sin (result2) in radians
set [temp v] to (result)
cos (result2) in radians
change [result2 v] by (((result) - (y)) / (temp)
end
set [result v] to (result2)

define arccos (y) in degrees
arccos (y) in radians
convert result to degrees

define arctan (y) in radians
set [result2 v] to [1]
set [previous result2 v] to [0]
repeat until <(previous result2) = (result2)>
set [previous result2 v] to (result2)
// tan(x) - y = 0 => x_n+1 = x_n - (tan(x_n) - y / sec(x_n)^2) = x_n - (sin(x_n) * cos(x_n) - y * cos (x_n) ^2)
sin (result2) in radians
set [temp v] to (result)
cos (result2) in radians
change [result2 v] by ((((y) * (result)) * (result)) - ((temp) * (result))
end
set [result v] to (result2)

define arctan (y) in degrees
arctan (y) in radians
convert result to degrees

define floor (x)
set [result v] to ((round (x)) - (0.5))

define ceil (x)
set [result v] to ((round (x)) + (0.49999999999))

define abs (x)
if <(x) < (0)>
set [result v] to ((0) - (x))
else
set [result v] to (x)
end

Edit: Need to do the inverse trig functions in radians because I'm differentiating them. Added conversions to degrees.

Edit2: Fixed a couple of typos and added a couple more explanatory comments

Edit3: Fixed the square root block, which was incorrect (made a silly mathematical error), and added abs

Last edited by joefarebrother (May 1, 2016 20:47:15)



And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
bobbybee
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

- omitted -

That's beautiful <3

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
DigiTechs
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

bobbybee wrote:

joefarebrother wrote:

- omitted -

That's beautiful <3

Literally this. My jaw just dropped.

I do, in fact, have my own site; it's here.
I'm also working on a thing called Fetch. Look at it here!
@thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain. @thisandagain pls explain.
joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

I looked at the wiki, and noticed I forgot abs, so I edited the post

Last edited by joefarebrother (May 1, 2016 19:23:52)



And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
bobbybee
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

I looked at the wiki, and noticed I forgot abs, but it's really easy, and here it is:

define abs (x)
if <(x) < (0)>
set [result v] to ((0) - (x))
else
set [result v] to (x)
end
Or you could use one of those nifty one liners.

((x) - ((2) * ((x) < [0]))

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

bobbybee wrote:

Or you could use one of those nifty one liners.

((x) - ((2) * ((x) < [0]))
Interesting, I didn't know booleans were automatically typecast into numbers!


And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
bobbybee
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

bobbybee wrote:

Or you could use one of those nifty one liners.

((x) - ((2) * ((x) < [0]))
Interesting, I didn't know booleans were automatically typecast into numbers!
Euhh…. they sometimes are. Sometimes they're not. You have to be careful about it

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
MegaApuTurkUltra
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

All that work just to remove 1 block

$(".box-head")[0].textContent = "committing AT crimes since $whenever"
bobbybee
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

MegaApuTurkUltra wrote:

All that work just to remove 1 block
I imagine my solution is more efficient, though?

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
theonlygusti
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

MegaApuTurkUltra wrote:

All that work just to remove 1 block
I mean, that is what this thread is about xD

joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

I'm just testing my maths workarounds now, and so far they are really fast on run without screen refresh!


And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
theonlygusti
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

I'm just testing my maths workarounds now, and so far they are really fast on run without screen refresh!
Nice! I must say, they are pretty impressive! You get all the internets!

bobbybee
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

joefarebrother wrote:

I'm just testing my maths workarounds now, and so far they are really fast on run without screen refresh!
…What about compared to the native versions?

“Ooo, can I call you Señorita Bee?” ~Chibi-Matoran
joefarebrother
Scratcher
500+ posts

Fewest amount of blocks technically needed to use Scratch

Haven't done any comparisons yet, but I will do when I finish implementing them.

Unfortunately, ln is REALLY slow for big numbers. Not because it has to call e^ a lot, but because when passed a big number, it has to “step down” to the true value in increments of basically 1, because it is calling e^-(big number) (which I made a few tweaks to e^ to accommodate for anyway) to determine how much to go down by, which return 0 or very close to it.

Fortunately, I'm looking into an alternative way to calculate ln, which is the taylor series for arctanh, which is really easy to implement.

But I'm going to bed now, I'll do more in the morning.


And it was delicious! Play TBGs! Check out my Scheme Interpreter!
;
PullJosh
Scratcher
1000+ posts

Fewest amount of blocks technically needed to use Scratch

bobbybee wrote:

joefarebrother wrote:

- omitted -

That's beautiful <3
I am reminded, now, of why I want a “like post” button.
(Someone make a userscript and grab a server from ascom to store votes. :P)

Powered by DjangoBB