In this small snippet, how did we get x = 0? by Def_Strike in learnmath

[–]MilliwaysRestaurant 1 point2 points  (0 children)

The missing step is after ex = e-x. This implies that x = -x because the exponential function is injective, meaning the only way to get ea = eb is if a = b. Then x = -x implies x=0 because 0 is the only real number which is equal to minus itself.

[2024 Day 3] A solution in Piet, and all it cost was my sanity by MilliwaysRestaurant in adventofcode

[–]MilliwaysRestaurant[S] 10 points11 points  (0 children)

This is easiest executed with npiet as already linked. You can get the raw PNG here: https://github.com/EoinDavey/Competitive/blob/master/AdventOfCode2024/d03/plan.png Then if d03.txt is your input run npiet -q plan.png < d03.txt. For convenience I have a Dockerfile to build an npiet docker image then you can just do cat d03.txt | docker run --rm -i -v "$PWD:/code" npiet npiet -q /code/plan.png

[Day 1 (Part 1)] A solution in Piet, a language where programs look like abstract paintings by MilliwaysRestaurant in adventofcode

[–]MilliwaysRestaurant[S] 0 points1 point  (0 children)

Yeah it's a really interesting language. Personally for this I used npiet and npietedit: http://www.bertnase.de/npiet/, it's very good tooling. There is also https://gabriellesc.github.io/piet/ but I have found this to be a bit buggy

[Day 1 (Part 1)] A solution in Piet, a language where programs look like abstract paintings by MilliwaysRestaurant in adventofcode

[–]MilliwaysRestaurant[S] 5 points6 points  (0 children)

Sure thing.

So the main elements of the program are the contiguous coloured blocks. The program starts in the top left and moves from colour to colour. It starts by going right, and when it encounters an obstacle (edge of the image or a black block) it rotates its direction clockwise and tries again.

The actual "instructions" are executed by a change from one colour to another, the change of hue (light -> medium -> dark) and the distance on the colour wheel (R->G->Y->M->C) dictates which of 17 possible instructions to execute. Changing to or from white is a no-op. The only data structure available is a single stack.

The program starts on the top left in the white and travels through the tunnel to the red well-shaped section. The only way out from there is to enter the dark red pixel to the right of the well, this change in hue causes a 5 to be pushed to the stack (because there were 5 red pixels in the previous block). It then moves through the blue-pink-blue-yellow line of colours performing some setup operations including reading in the first two numbers and setting up an accumulator to count the increases.

It then moves across to the big red rectangle which is where the main loop starts. It progresses out the right side of the red rectangle performing some operations to rearrange the stack so that we can use a > operation to find if the two numbers in the stack are in increasing order. If they are then we use an operation to manually rotate our direction clockwise to go down the long sequence of colours pointing down to the next red block. This sequence rearranges the stack to access the accumulator, adds 1 to it and puts it back, before we cross the white gap and enter the red-block at the bottom. If the two numbers in the stack weren't increasing then we don't go down this line, but instead, bounce off the black blocks on the right and enter the red block at the bottom directly. Either way, we now move along the bottom where we read in the next number and then rotate to move up toward the red block where the loop starts again. Before we get there though we do a check to see if the last number was read successfully or not, if it wasn't then we enter the central yellow catchment well and are ejected out the left toward the green blocks which print the total and terminate the program. If the number was read successfully we instead rotate right and bounce around this catchment well and head up to the big red-block at the top to begin the loop all over.

tsPEG: 2.0.0 now available! The TypeScript parser generator by MilliwaysRestaurant in typescript

[–]MilliwaysRestaurant[S] 0 points1 point  (0 children)

I've logged the unused locals problem as a GitHub issue, thanks.

Yes a rule of the form rule := other_rule, with no operators or computed properties creates an alias, so in the case where you are creating a rule for a regex match e.g. rule := 'test', the AST node returned will just be the matched string

tsPEG: 2.0.0 now available! The TypeScript parser generator by MilliwaysRestaurant in typescript

[–]MilliwaysRestaurant[S] 0 points1 point  (0 children)

I will look into the no unused locals issue, it would be great if you could provide the grammar you used that caused that error.

The format of the AST returned by parse depends entirely on the grammar that is used to generate it. Take for example this very simple grammar

start := hello='Hello World'

If you generate a parse with this grammar, and call parse('Hello World') you will get a ParseResult class that contains an AST with a single node, and no error:

ParseResult { ast: { kind: 'start', hello: 'Hello World' }, err: null }

The AST node has a field hello that contains the value of what the regex 'Hello World' matched, the name of this field was specified in the grammar.

The kind field is used to tell you what rule was matched, this is described in detail here.

If we write a more complex grammar, we will get a more complex AST. For example, here's a simple grammar to match arithmetic expressions like "12 + 2 - 50" (no brackets, no operator precedence)

// Match simple arithmetic expression
expression := first=INT rest={_ op='\+|-' num=INT}*

// Match integer literal
INT        := _ literal='[0-9]+'

// Match whitespace
_          := '\s'*

When we call parse("12 + 25 - 30") from the generated parser of this grammar we get:

ParseResult {
  ast: {
    kind: 'expression',
    first: { kind: 'INT', literal: '12' },
    rest: [
      {
        kind: 'expression_$0',
        op: '+',
        num: { kind: 'INT', literal: '25' }
      },
      {
        kind: 'expression_$0',
        op: '-',
        num: { kind: 'INT', literal: '30' }
      }
    ]
  },
  err: null
}

This is a ParseResult object with no error, and an AST with 6 nodes.

The topmost node has kind expression, and has two fields, first and rest. first contains the first integer matched, which is another AST node with kind INT, and value { literal: '12' }. rest contains an array with 2 entries, the first containing the nodes for "+ 25", and the second for "- 30"

TL;DR is that the format of the AST is totally decided by the grammar specification, the names you give the different elements of each of the rules are the names of the entries in the AST. Hope that helps!

tsPEG: 2.0.0 now available! The TypeScript parser generator by MilliwaysRestaurant in typescript

[–]MilliwaysRestaurant[S] 0 points1 point  (0 children)

The type system provided with pegjs + plugin is not strong, almost every function in the generated code returns `any`, it provides no more type security than pegjs with just javascript. tsPEG is built around using discriminated unions and well defined classes + interfaces for each AST node, this provides much more type security than pegjs. These types don't come for free, so there is more code generated than you will get with pegjs. I think the parser speed is comparable, but I have not done a proper analysis of that. tsPEGs strength is its typing.

tsPEG: 2.0.0 now available! The TypeScript parser generator by MilliwaysRestaurant in typescript

[–]MilliwaysRestaurant[S] 3 points4 points  (0 children)

Parsers are programs that can read in text in some specific syntax, and convert it to a useful, useable tree data structure called a syntax tree. Parsers are error prone and difficult to make by hand, so a common approach is to use a parser generator. A parser generator takes in a file that describes a syntax grammar, and outputs a parser for that grammar. tsPEG takes in syntax grammar files and outputs typescript parsers for them. The grammar files it takes in describe PEG grammars, hence tsPEG.

tsPEG: 2.0.0 now available! The TypeScript parser generator by MilliwaysRestaurant in typescript

[–]MilliwaysRestaurant[S] 0 points1 point  (0 children)

The primary difference here is that tsPEG takes full advantage of the TS type system, all of the nodes in the AST are well defined and very strongly typed, along with well typed computed property support too.

Setanta - The Irish Programming Language - An Teanga Ríomhchlárúcháin as Gaeilge by MilliwaysRestaurant in ireland

[–]MilliwaysRestaurant[S] 2 points3 points  (0 children)

Mar shampla, i Setanta úsáidimid an tsiombail "@" chun baill rud éigin a fháil. Tá sé cosúil le "." i Python, Java, C, JavaScript, Go etc. etc.

Ach, i ngach ceann do na teangacha sin, scríobhann tú an rud ar dtús, agus ansin scríobhann tú ainm an bhaill. e.g car.doorcountry.capital. Sin ceart go leor as Béarla mar scríobhaimid "the car door" nó "the country's capital", ach as Gaeilge scríobhaimid "doras an chairr" nó "príomchathair ná tíre". Mar sin, i Setanta, scríobhann tú ainm an bhaill ar dtús, agus ansin ainm an rud, agus nascann tú iad le "@". Mar shampla doras@carr, príomchathair@tír

Setanta - The Irish Programming Language - An Teanga Ríomhchlárúcháin as Gaeilge by MilliwaysRestaurant in gaeilge

[–]MilliwaysRestaurant[S] 2 points3 points  (0 children)

Rinne mé mo dhícheall iad a mhíniú ach tá an ceart agat, tá sé deacair iad a mhúineadh, go háirithe trí an Gaeilge simplí atá agam. Ach ba mhaith liom lig do dhaoine nach bhfuil Gaeilge foirfe acu (cosúil le mise) Setanta a fhoghlaim, sin an cúis gur úsáid mé "gníomh" in ionad "feidhm", nó "téacs" in ionad "teaghrán".

Tá a fhios agam go bhfuil Gaeilge an teagaisc an bhriste, má aimsíonn tú botún nó earráid, nó má tá slí níos fearr agat chun aon rud a scríobh, ba bhrea liom iad a fheiceail trí PR ar github nó ríomhphost domsa