Tips for golfing in Japt

18

5

Now that I'm thoroughly addicted to Code Golf, it's probably about time that I try to pick up a few golfing languages.

Given that I play almost exclusively in JavaScript, Japt seems like the logical language to start with. I'll be diving into the documentation at the next opportunity I get but, in the meantime, please post any tips you have for Japt in the answers below.

As I'm a beginner in Japt and golfing languages in general, if you could "translate" your tips to JavaScript, where possible, that would be a big help in helping me get to grips with things.

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

Heh, thanks for posting this. I'd been holding off on doing this because I'd like to redesign Japt at some point, but that won't be happening anytime soon, and it probably won't mess up a lot of the tips anyway. Tip for myself: write a tutorial :P – ETHproductions – 2017-05-17T21:31:38.893

Don't forget to visit the Japt chatroom :)

– Oliver – 2017-05-18T14:53:05.877

Answers

11

Moving from JavaScript to Japt

As you may know, Japt is simply a shortened, extended version of JavaScript. I created Japt because I was tired of long property names, like String.fromCharCode(x) and Math.floor(x), and the tediousness of doing things such as creating a range. Here's the bare minimum you need to know when going from JavaScript to Japt:

  • Japt is a transpiled language; Japt code is transpiled to JavaScript and then run as JS. (I guess you could say compiled, but transpiled sounds more hipster. Disclaimer: I know absolutely nothing about being hipster)
  • All entries are full programs by default. The input is implicitly parsed, and the first six inputs are put into the variables U, V, W, X, Y, and Z; the full array is stored in N. The result of the last expression is automatically printed.
  • All uppercase letters are variables, and stay the same when transpiled. Most have preset values, which you can find in the "Variables" section of the Japt docs (at the interpreter).
  • All lowercase letters are prototype functions, or methods. Japt adds the methods a-z (and à-ÿ) on numbers, strings, and arrays. When you use one of these letters, Japt fills in the . and (; Uc in Japt is equivalent to U.c( in JavaScript, which could mean ceil, charCodeAt, or concat, depending on the type of U. This is where most of Japt's power comes from; you can find full lists of these methods under the "_____ functions" sections of the Japt docs (at the interpreter).
  • A space represents ), and ) represents )). This is because when I first designed Japt, I wanted to save as many bytes as possible, and that's how I first thought of doing this. (Though Us w n does look better than Us)w)n), IMHO.)
  • A function is denoted as ABC{...}, where the ABC can be any string of variables. Functions work for the most part as they do in JS, the main difference being the last expression is automatically returned (rather than having to use return or fancy ES6 parentheses).
  • ' denotes a single char string (i.e. 'a is the same as "a"), and # takes the next char-code and becomes that number (#e is the same as 101).
  • Anything between dollar signs $ stays the same during the transpilation process. You can use this to implement for loops, for example, since Japt doesn't have those, but I would suggest using other methods (such as m on strings and arrays, or o on numbers).
  • Most other chars commonly used in JS — "", 0-9, (, +, =, etc. — stay the same when transpiled (for the most part, anyway).

And that is all you need to know to write basic Japt code. Achieving maximum golf power in Japt requires more knowledge, but that can be found in other answers.


Here's a basic example. Say you have want to take a string of ASCII characters and replace each with its hexadecimal char code. Here's how you might do that in JavaScript:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Now to convert to Japt. .split("") in JS is equivalent to q"" in Japt, or even shorter, just q. .join("") is also just q, the difference being that the object is an array instead of a string. .map( is m, .charCodeAt( is c, and .toString( is s. So our Japt code might look like:

Uq mX{Xc0 s16} q 

In Japt, though, m works as well on strings as it does on arrays, so we can remove both qs:

UmX{Xc0 s16}

Test it online! As you can see in the "JS code" box, this directly transpiles to:

U.m(function(X){return X.c(0).s(16)})

As you learn to work with Japt, you'll become less and less focused on converting back and forth from JavaScript and be able to code in Japt as its own language. Here's an explanation leaving out the JavaScript portion entirely:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

It might be better to show another step: the unicode shortcuts. In this case, we coould save 2B with them. Also, you might want to add that you can leave out certain things at the end. That would save another byte. – Luke – 2017-05-18T06:15:33.320

An excellent primer, thanks, ETH. There's enough there, I think, to get me started on a few simple challenges. – Shaggy – 2017-05-18T06:18:27.543

Combining this with what I've gleaned from the README so far, would I be correct that the example above could be further shortened to Um_c s16? – Shaggy – 2017-05-18T06:30:27.153

Or, shorter still: ¡Xc s16? – Shaggy – 2017-05-18T10:54:42.847

1@Shaggy You're correct! Man, you've figured this out quick ;-) I'll add some basic Japt golfing tips (like Unicode shortcuts and such), probably as other answers though. – ETHproductions – 2017-05-18T12:18:51.737

It's tricky in parts, but overall it's been easy to pick up so far. I just need to work on better golfing and not being so reliant on the documentation (that'll come in time). I've been working on porting some of my existing JS answers to help me get to grips with things; would you mind throwing an eye over them for me, when you have a minute? Here's one (JS) and here's the other (JS).

– Shaggy – 2017-05-18T12:34:36.470

The second one in particular needs some work as I had to work around the fact that array indexing wraps in Japt. – Shaggy – 2017-05-18T12:35:20.807

Wow! I am definitely going to use Japt somewhere near in future! Thanks for this post! – Arjun – 2017-05-18T15:41:48.593

I'm going to accept this purely to keep it pinned to the top of the list of answers as it's probably going to be where most people will need to start. – Shaggy – 2017-05-18T20:07:09.840

I think this would work now: c_sGÃò – Embodiment of Ignorance – 2019-03-25T18:08:09.333

@EmbodimentofIgnorance In fact it can now be simply csG!

– ETHproductions – 2019-04-25T04:12:22.947

8

Compressing String Arrays

UPDATE: The tools featured in this tip have since be rewritten, improved and integrated into my Japt interpreter. For the best results it is recommended that you use that compressor over any of those linked below. I'll revisit this tip when I have some more time and rewrite it with the new compressor in mind.

Introduction

If you have an array of strings in your code, the most obvious way to compress it would be to run each string through Oc individually. For the purposes of this tip, we'll be working with the array ["lollipop","marshmallow","nougat","oreo"], which weighs in at 42 bytes initially. Running each string through Oc gives us:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

That's now 33 bytes, a decent saving.


Step 1

But, we can do better. If we join the array to a newline separated string, we can get rid of the brackets, commas, and extraneous backticks and split on newline to get our array. Applying that to our example array gives us the following:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Down to 26 bytes now.


Step 2

But, we can do better still! We could use a lowercase letter to delimit the strings instead of a newline, which might get included in the compression. z isn't used in any of our strings so let's drop that in, and see how we get on.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, nuts - no improvement there; our byte count has gone up by one! There might be another letter you could use but, depending on your strings, there could be quite a few to try - in our example there are 11: b,c,d,f,j,k,q,v,x,y,z. Trying each would be pretty tedious, which is where this handy tool comes in; feed it your newline separated strings and it will try to delimit the strings with each letter that's not contained in any of them and output:

  • the shortest compressed string,
  • the delimiter it uses, and
  • its length.

Running our sample strings through it shows that b gives the best results:

`lo¥ipáæqrÚaowbÍÞo`qb

And there you have it, we're down to just 24 bytes.


Step 3

But, we can do even better! If the order of strings in your array doesn't matter, maybe there's a different permutation combined with a different delimiter that could work out even shorter. Trying each possibility is going to be much more tedious, though. With our 4 strings, there are 24 different permutations to try. With each of the 11 possible letters that becomes 264! That's where this tool comes into play. Again, feed it your newline separated strings and it will try every combination of every permutation and every delimiting letter, outputting:

  • the order of the strings in the shortest compressed string,
  • the compressed string,
  • the delimiter it uses, and,
  • its length.

Running our sample strings through it shows that "nougat","oreo","lollipop","marshmallow" with b as a delimiter gives the best results, with a final byte count of just 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Bonus Tip: Integer Array Compression

You can apply the same principle to arrays of integers by first converting each to a higher base. Using this sample, 36 byte array:

[588181,156859,595676,475330,680474]

We can get that down to 29 bytes by first converting it to an array of base 32 strings and then running it through the first compression programme:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Or as low as 27 bytes using the second programme:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

You might be able to save another byte or 2 on top of that by moving the integer conversion into a method you're already running on the array.


Notes

  1. Don't forget to factor in the 1 or 2 extra bytes q<letter>(<space>) costs over ·. Although, you may be able to use one of the Unicode shortcuts to get a byte back, depending on your delimiter ( is the same as ql<space>, for example).
  2. A word of caution when using the last tool: the more strings you have, the more permutations there will be and the slower the programme will run, until it eventually craps out. As detailed above, with our 4 sample strings and 11 possible letters to try, there are 264 possible combinations, increase the number of strings by just 1 with the same 11 letters and we already have 1320 combinations to try. (You can use this tool to count the number of combinations, if you want).

Credits

  • Oliver for the inspiration to create the tools found in this tip.
  • ETHproductions for proofreading.

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

6

Shortening Numbers With Char-Codes

In Japt, you can use #, followed by a character to create a char-code. This comes in handy when shortening longer numbers.

As @ETHproductions mentioned, this only works on three-digit runs in the range 100-255, unless you are willing to switch to UTF-8.

Examples:

123 can be shortened to #{

101 can be shortened to #e

You can even chain these together:

123101 can be shortened to #{#e

You can use String.fromCharCode(123) in JavaScript, or 123d in Japt to find the appropriate character.

String.fromCharCode(123) returns {

Oliver

Posted 2017-05-17T21:04:28.700

Reputation: 7 160

Thanks, @obarakon, great tip to get the ball rolling with; String.fromCharCode() is one of those (many!) nastily​ long JS methods that can tank your byte count. Presumably, these would be considered to be integers? i.e., if I have need of the integer 123 in a solution, I could use #{ to save a byte. – Shaggy – 2017-05-17T21:57:44.773

1

Yes, these are integers. If you add the -Q flag into your input window, you can better view the output type: quotes around strings, arrays, etc.

– Oliver – 2017-05-17T22:01:29.573

1You should mention that String.fromCharCode(123) works in JavaScript, but you can do 123d in Japt to get the same result ;-) Also, this only works on three-digit runs in the range 100-255 (unless you're willing to switch to UTF-8) – ETHproductions – 2017-05-17T22:07:52.810

@ETHproductions Good call, updated! – Oliver – 2017-05-17T23:09:49.027

6

Compressing strings

Japt (currently) uses the shoco library for string compression. You can compress an arbitrary string using Oc, as long as it contains runs of lowercase letters:

Oc"Hello, World!"

This outputs HÁM, WŽld! (well, the Ž is technically an unprintable character). You can decompress this by wrapping it in backticks:

`HÁM, WŽld!`

Test it online!

Alternatively, you can use the Od function to decompress an arbitrary string. This isn't usually useful, but it has its purposes...

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

So, if I were answering the "Hello, World!" challenge, would I use just HÁM, WŽld! or would it need to be enclosed in backticks? I'm guessing the latter. – Shaggy – 2017-05-18T06:16:30.597

2@Shaggy When answering a question you'd need to include all the code, so that would be `HÁM, WŽld! in this case – Martijn Vissers – 2017-05-18T07:08:00.820

5

Quick tip: Empty array []

Japt has a constant for an empty array: A. But, in order to access it, you must prepend a semicolon ; to your programme to use Japt's alternative constants, otherwise A will be 10. So using ;A actually offers a 0 byte saving over [], but will save you bytes if you need to assign your array to a variable (e.g., A=[]).

However, if (and only if) your programme is not taking any input, you can access the empty array with just 1 byte by using the N variable, which is the array of inputs - with no inputs, it would be empty. Try it out here.

This has also has the added benefit of allowing you to use the default constant values in your programme and, in some cases, can still save you bytes over using ;A even when your programme is taking input thanks to the shortcuts for s1 and s2.

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

2Wow, I hadn't thought about using N, nice idea. – ETHproductions – 2017-05-19T12:03:51.237

2Nice one, @Shaggy! – Oliver – 2017-05-19T14:02:48.610

4

Evaluating JavaScript

Japt allows you to execute raw JavaScript by wrapping it around $...$.

For example, $alert("hello world")$

This can be shortened by taking advantage of Japt's auto-closing $ and ).

$alert("hello world")$ can be shortened to $alert("hello world"

Compressing JavaScript

You can also compress JavaScript using Ox.

If there is a JavaScript function that you want to use, say screen.width, you can compress the string "screen.width" using Oc, then inserting the result in between Ox`...`

Note that you do not need closing quotes in Japt when it is not followed by anything else.

Oliver

Posted 2017-05-17T21:04:28.700

Reputation: 7 160

@Shaggy You need the Ox to evaluate the string. Otherwise, you would just output the text "screen.width". Example

– Oliver – 2017-05-18T13:06:59.440

4

Know the flags

As per the latest meta consensus (Dec 2017), command-line flags are no longer counted towards bytes. It's really a great news for Japt since it has many flags for extra treatment on input/output.

All available flags in Japt are described below, in the order of evaluation. The flags in the same group are exclusive to each other. Note that the flags in different groups can be used in combination, resulting in something like this :)

mdefæ

The whole program is mapped over the first argument (U).

If more arguments are present, they are passed as-is (i.e. not pairwise mapped). Otherwise, the second argument is the index, and the third is the whole array, just like U.m. If U is a number, it is converted to range; if string, it's converted to array of chars and the results are joined together.

  • -m: Applies the above and nothing else.
  • -d: Returns true if some result is truthy, false otherwise.
  • -e: Returns true if all results are truthy, false otherwise.
  • -f: Returns the array of elements of U whose results are truthy.
  • : Applies -f and returns its first element.

gh

Takes an element at the specified index.

  • -g: Takes first element (index 0).
  • -gX: Takes the element at index X (can be any positive integer).
  • -h: Takes last element.

Convert the result to boolean.

  • -!: Apply boolean not.
  • : Apply boolean not twice (returns the truthiness).

N

Convert the result to number. The unary plus is used.

PRSQ

Convert to string of some sort.

  • -P: Join the array with "".
  • -R: Join the array with "\n".
  • -S: Join the array with " ".
  • -Q: Apply JSON.stringify (can be any object, not only an array). Example.

x

Applies the function x to the output. (It's literally x, not "any single lowercase alphabet function".)

  • Array: Sum.
  • String: Trim from both ends.
  • Number: Round to integer.

Bubbler

Posted 2017-05-17T21:04:28.700

Reputation: 16 616

2Note that using flags doesn't count as a Japt submission though, it counts as a Japt-with-those-specific-flags-language submission. – Nit – 2018-07-17T08:04:10.870

3

Unicode shortcuts

There are many common structures in Japt that just can't be stored in a single ASCII char, such as qS , p2 , mX{, , etc. So to get around this, Japt has "Unicode shortcuts", which are characters in the range \xA1-\xDE (¡-Þ) which expand to these common structures. You can find a full list of these in the interpreter docs.

Additionally, @ stands for XYZ{, and _ stands for Z{Z, to help build functions. So let's golf our example program from another answer:

UmX{Xc0 s16}

Firstly, we can replace X{X with _, which gives us:

Um_c0 s16}

Then we can replace m_ with ® saving another byte:

U®c0 s16}

Or we could replace X{ with @, which gives us:

Um@Xc0 s16}

This then allows us to use the ¡ shortcut to save two bytes:

¡Xc0 s16}

One of these two paths can be shortened 1 byte more than the other. Can you figure out which?

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

1®c s16 for 6 bytes - do I win a cookie?! – Shaggy – 2017-05-18T14:02:08.600

@Shaggy You can save 1 more byte if you look hard enough... ;) – ETHproductions – 2017-05-18T14:19:34.687

Would it be ®c sG? – Shaggy – 2017-05-18T14:20:29.443

1Yep! I think that's as low as you can go. Well done! :-) – ETHproductions – 2017-05-18T14:23:09.290

2Amazing looking back on these, seeing the progression of Japt in a few short months. This can now be achieved with csG. – Shaggy – 2017-09-13T22:10:09.370

With the addition of Ë, another byte can be saved at the start now. – Nit – 2018-04-06T11:32:53.740

3

Take advantage of preset variables

Variables A-S are preset to common values that take more than one byte to represent in Japt:

  • A-G are 10-16.
  • H is 32, I is 64, J is -1, L is 100.
  • K is defined as new Date(), which you can manipulate in various ways.
  • M and O are objects with various useful functions. You can learn more in the docs.
  • P is the empty string, Q is a quote mark, R is a newlines, and S is a space.
  • T is set to 0, so you can use it as an accumulator if necessary.

If the first character in the program is a semicolon ;, A-L are reset as follows:

  • A is the empty array [].
  • B is "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • C is "abcdefghijklmnopqrstuvwxyz".
  • D is "QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • E is "[a-z]", and F is "[A-Za-z]" (useful before I added these as regex features)
  • G is 36, H is 65, and I is 91 (useful for alphabet ranges).
  • J is a single comma; L, a single period.

Nowadays only A, B, C, and D from this list are really useful. I'm planning to add a better system which allows up to 256 two-byte variables, which will be preset to these values and a whole lot more.

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

3

Use auto-functions

You most likely already know that @ and _ are shortcuts for XYZ{ and Z{Z, respectively (covered in the Unicode shortcuts answer). But sometimes you can make functions even shorter.

Suppose you had an array of characters and you wanted to map each character to its char-code. You could do this with either of these:

mX{Xc} 
m_c} 

But there's a better way. If a method or operator is the first item after another method or a (, it gets turned into a string. So these two lines are equivalent:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

But how does that help with our functions? Well, most methods that accept functions, if given a string representing a method or operator, will interpret it as a function. Which means you can also do this:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

I call these "auto-functions". There are several different varieties:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Hopefully you get the idea. To swap the arguments, just prefix the method or operator with !.

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

Would it be worth noting here that using auto-functions can also allow for further savings through the use of shortcuts? e.g., m@2pXÃm!p2<space>m!². – Shaggy – 2017-09-13T21:51:24.600

Woah! I didn't thought about using a string in map, didn't even know it's possible. Maybe I'll save few bytes thanks to this in the future. – RedClover – 2018-01-12T14:38:34.913

Hey @Soaku, I somehow missed that you've been answering with Japt, so allow me to extend you a late Welcome! Hope you've enjoyed using it so far. If you have any questions, suggestions, or just want to talk, feel free to join us in the Japt chatroom (Github usually works as well for the first two ;) )

– ETHproductions – 2018-01-13T00:22:51.930

3

Implicit Variable Assignment

Whenever you start a new line in Japt the result of the previous line is automatically assigned to one of the input variables (U-Z), with the first line being U, the second V, and so on.

Let's take an example: say you wanted to create 2 arrays to work with, one containing the numbers 1-10 and the other containing their squares. The long way to do this would be like so:

U=Aõ V=Um² [do something with the arrays]

Using automatic variable assignment, though, that can be shortened to:

Aõ
Um²
[do something with the arrays]

We've saved 4 bytes there. But, in this instance, we can save one more byte because the array of 1-10 is assigned to U and U can be omitted in certain scenarios:

Aõ
m²
[do something with the arrays]

Caution

One thing to be careful of with this tip is that you don't overwrite any input variables you might need later on in your programme. This can be avoided by leaving one or more empty lines at the start of it. In the following example, the 2 arrays will be assigned to the variables V & W, instead of U & V:


Aõ
Vm²
[do something with the arrays]

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

3

Know the Javascript

Since any Japt code runs as transpiled JS, good understanding of JS operators and built-in methods helps a lot in golfing pieces of Japt code.

Relevant JS tips

[]Vm@...
...
  • Short-circuiting
  • Splitting with numbers
    • This can be generalized to any method that accepts strings but not numbers. A number passed there will implicitly cast to a string, often saving a byte (e.g. 0 over '0).

Relevant JS built-in functions

Closely look at what parameters are passed to function arguments.

For string methods, it's good to know how the behaviors differ between passing a string or regex with or without g flag.

Bubbler

Posted 2017-05-17T21:04:28.700

Reputation: 16 616

3

Use multiple lines when necessary

For most not-too-hard challenges, you can express the solution in just one line of Japt, as a sequence of applying built-in functions. But more complex ones will require to use looping constructs, recursion, or reusing large chunks of code. This is where multi-line programming comes in.

Remove closing parens

Task: Given an array of numbers, pair each element with the index squared, and sort it by the sum.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

One-line solution is íUm@Yp2})ñx, but }) costs two bytes (and there is no one-byte shortcut). You can remove }) by simply moving the trailing ñx to the next line, so the code looks like this:

íUm@Yp2
ñx

and the transpiled JS becomes:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

You can clearly see this does the same thing as the one-line solution, just assigning the intermediate result back to U.

Recurse with implicit arguments

The recursion function ß takes all of UVWXYZ as implicit parameter, if not specified. U is obviously the main input, but you can use any of VWXYZ to keep track of other values you need. For example, you can do something like the following:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Alternatively, if all you want is a temporary variable, you can use inline assignment, like (T=...), as the variable T (0) is rarely used as-is.

Reuse a long function

For this, I don't think I can come up with a good example task, so I'll reference the only solution this tip was used, and just outline some general ideas.

  • In order to reuse a function, you need to store it in a variable. Starting a line with the function-opener {, @ or _ does the job. Alternatively, you can also do something like (T=@...}) to embed the function assignment inside a more complex line.
  • It's actually not trivial to call the stored function. Suppose V is a function and we want to call V(U) in JS. VU does not work since it simply means V,U. V(U doesn't either; it's V,(U). Even the function methods aren't helpful very much. The best way we found is:
    • [U]xV (map and sum) if the result is number
    • UmV if U is a single char and V returns a string, or
    • $V($U or [U]mV g in general.
  • However, mapping or looping with it is rather easy. To map over an array, use UmV. To find the first integer that satisfies V, use Va.

Bubbler

Posted 2017-05-17T21:04:28.700

Reputation: 16 616

2

Fun with Auto-Functions

As a follow-up to ETH's general tip on auto-functions, this tip will provide a few specific examples of byte saving tricks you can achieve with them, which I'll add to as I think of more.


Get the largest integer in an array.

Assume we have the array [3,1,4,2] assigned to variable U and we ant to retrieve the largest number from it. We could do it in 4 bytes by sorting the array and then popping the last element:

Un o

The downside to that is that we've modified the original array; U is now [1,2,3] which may not always be desirable. Luckily, there's a way of doing it without modifying the array that's also one byte shorter:

Urw

What we've done there is reduced the array using the w method, which, when used on an integer returns the larger of the integer and the method's argument (e.g., 2w5 returns 5). So the above is the equivalent of UrÈwY or UrXY{XwY}. Note, though, that this tip won't work in the case of all the integers in the array being negative.

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

1Side note: I'm planning to add functions to get the min and max of an array, though probably only in v2. – ETHproductions – 2017-07-10T17:23:46.820

2

When not to use í

í is a useful built-in that pairs (or zips) two arrays or strings, and optionally maps each pair through a function. However, it currently has a few minor issues when given uneven arrays or strings:

  • If the first array has more items than the second, the non-existent items in the second will be given as undefined.
  • If the second array has more items than the first, it will stop processing at the end of the first array.

This can make it difficult to, say, compare two uneven strings and take the char with the higher code point from each pair. Even if you know that U is going to be the longer one, it still takes far to many bytes to solve this simple task:

UíUç hV @[XY]n o

What you could do instead would be to take input as an array of two strings, transpose the array with y, and then map each row to the correct result:

Uy m_q n o

This has the advantage of always padding the shorter string with spaces, making it a piece of cake to go through the entirety of both strings.

Real-life examples: 1, 2

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

2

Generate the ASCII Range

Update: Japt now has a constant for the ASCII range; the alternative value for E, accessible with ;. See this tip for more on Japt's constants.

While Japt doesn't (yet) have a built-in for the ASCII range, you can generate an array of characters in just 5 bytes:

95odH

Try it


How It Works

95o creates the range [0,95) with each element being passed through the auto-function d which, when used on a number, returns the character at that codepoint. Pass a number as an argument to the d method, in this case H, the Japt constant for 32, and it will be added to the original number before being converted.

An equivalent solution in JavaScript would be:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Random Characters

To get a random character in the ASCII range, use ö instead, which returns a random number from the range [0,X), where X is the number it is run on.

95ö dH

Or, to get an array of multiple random characters, pass the number of characters you need as an argument of ö. The following will return 10 characters:

95öA mdH

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623

1

Remove unnecessary structural chars

By structural chars, I mean {}, (), $, even " and `. You can typically remove these chars whenever they occur right at the end of a program (e.g. UmX{Xc +"; "} -> UmX{Xc +"; ).

Additionally, you can remove parens or spaces whenever they appear in the following places:

  • Up against a semicolon ; (or the end of the program);
  • To the right of { (and by extension, @) or [, or the left of ] or }.

Also, commas are very rarely needed to separate arguments. If you write AB, for example, Japt knows you mean A and B separately. You only really need a comma to separate two numerical literals, such as Us2,5.

Finally, if there's a U at the start of a program or after a { or ;, followed by a method call (lowercase letter or related Unicode shortcut) or any binary operator excluding + and - (*, &, ==, etc.), you can remove the U to save a byte and Japt will insert it for you.

ETHproductions

Posted 2017-05-17T21:04:28.700

Reputation: 47 880

I've found a few other instances where U can be ommited even when it's not at the start of the programme. – Shaggy – 2017-05-18T19:55:45.643

@Shaggy Oh right, it also works after a { or ;. Are there any others that you are aware of? (It's been a while since I coded this feature :P) – ETHproductions – 2017-05-18T19:59:57.843

Can't think of them off the top of my head; I'll check it out again when I get back to my computer tomorrow. – Shaggy – 2017-05-18T20:03:44.980

1

Modify the Last Element in An Array

Sometimes you may need to modify the last element in an array so here's an explanation of a short way of doing that. We'll be working with the array [2,4,8,32] assigned to input variable U and dividing the last integer (32) by 2.

The obvious way to achieve this would be with this 9 byte solution (Demo):

UhJUgJ /2
  • hnx sets the element at index n to x.
  • gn returns the the element at index n.
  • J is the Japt constant for -1, which, thanks to Japt's support for negative index, allows us to work with the last element in an array; handy when you don't know the size of the array.
  • And /2 is simply division by 2.

So the above sets the element at index -1 in the array to the element at index -1 in the array divided by 2. Or in JavaScript: U[3]=U[3]/2. When you write it out like that, it seems a far too long-winded way of going about it. Luckily, there is a shorter way; we could pop the last element from the array, modify it and push it back to the array. Performing each of those operations individually would take more than 9 bytes but we can do them all at once for just 7 bytes, a 2 bytes saving (Demo)

UpUo /2

Translated to JS, it's the equivalent of:

U.push(U.pop()/2)&&U

Shaggy

Posted 2017-05-17T21:04:28.700

Reputation: 24 623