DEV Community

Cover image for OpenAI is shockingly good at unminifying code
Frank Fiegel
Frank Fiegel

Posted on • Originally published at glama.ai

OpenAI is shockingly good at unminifying code

While browsing the Internet for inspiration, I came across an interesting-looking component.

Image description

I thought the block with the running ASCII art looked cool, but I couldn't quite figure out how it was implemented, so I started looking at the source code.

I found the code that looked like it might be doing the job, but it was minified.

const { floor: ra, abs: KE, min: QE } = Math,
    O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"],
    G7 = Date.now() % 3 ? O5[1] : O5[0],
    V5 = G7.length,
    JE = { fps: 60 };
function eT(e, t, n, r) {
    const i = t.time * 8e-5,
        s = QE(t.cols, t.rows),
        o = t.metrics.aspect * 0.2,
        l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s },
        u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5;
    return G7[u];
}
const tT = () => {
    const e = j.useRef(null),
        [t, n] = j.useState({ height: null, width: null });
    return (
        j.useEffect(() => {
            function r() {
                n({ height: window.innerHeight, width: window.innerWidth });
            }
            if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r);
        }, []),
        j.useEffect(() => {
            const r = e.current;
            if (!r) return;
            const i = 12,
                s = ra(t.width / i) * 1.6,
                o = ra(t.height / i),
                l = { aspect: s / o },
                u = setInterval(() => {
                    let c = "";
                    for (let d = 0; d < o; d++) {
                        for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
                        c += `
`;
                    }
                    r.textContent = c;
                }, 1e3 / JE.fps);
            return () => clearInterval(u);
        }, [t]),
        a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) })
    );
};
function nT(e) {
    return Math.cos(e.x * e.x - e.y * e.y);
}
const { floor: ia, abs: rT, min: iT } = Math,
    D5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"],
    X7 = Date.now() % 3 ? D5[1] : D5[0],
    F5 = X7.length,
    sT = { fps: 60 };
function oT(e, t, n, r) {
    const i = t.time * 8e-5,
        s = iT(t.cols, t.rows),
        o = t.metrics.aspect * 0.2,
        l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s },
        u = ia(rT(nT(l) - i) * F5 + (ia(e.x / 1) % 2) * 2) % F5;
    return X7[u];
}
const aT = () => {
    const e = j.useRef(null),
        [t, n] = j.useState({ height: null, width: null });
    return (
        j.useEffect(() => {
            function r() {
                n({ height: window.innerHeight, width: window.innerWidth });
            }
            if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r);
        }, []),
        j.useEffect(() => {
            const r = e.current;
            if (!r) return;
            const i = 12,
                s = ia(t.width / i) * 1.6,
                o = ia(t.height / i),
                l = { aspect: s / o },
                u = setInterval(() => {
                    let c = "";
                    for (let d = 0; d < o; d++) {
                        for (let f = 0; f < s; f++) c += oT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
                        c += `
`;
                    }
                    r.textContent = c;
                }, 1e3 / sT.fps);
            return () => clearInterval(u);
        }, [t]),
        a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) })
    );
},
Enter fullscreen mode Exit fullscreen mode

Usually, I would just powerthrough reading the minimized code to understand the implementation (or look for a .map file to restore the original code). However, I realized that I never tried asking ChatGPT to do it for me... So I copied all of the above code and asked ChatGPT to "explain the code". Here is the response:

The provided code is quite complex, but I'll break it down into a more understandable format, explaining its different parts and their functionalities.

Overview

The code defines several functions and components using JavaScript, specifically in the context of a React application. It deals with generating some dynamic text content, presumably ASCII art or some kind of visual effect using characters from a predefined set. Additionally, it includes utility functions for event handling, performance timing, and HTML content conversion.

Key Components and Functions

  1. Character Set Selection:


``javascript
const { floor: ra, abs: KE, min: QE } = Math;
const O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^
'. .:â–‘â–’â–“â–ˆ"];
const G7 = Date.now() % 3 ? O5[1] : O5[0];
const V5 = G7.length;



   - This part of the code imports some common Math functions (`floor`, `abs`, and `min`) and defines two sets of characters, stored in `O5`. 
   - Based on the current time (`Date.now() % 3`), it selects one of these sets (`G7`) to use later.
   - The length of the selected character set is stored in `V5`.

2. **Dynamic Character Selection Function:**


    ```javascript
   function eT(e, t, n, r) {
       const i = t.time * 8e-5;
       const s = QE(t.cols, t.rows);
       const o = t.metrics.aspect * 0.2;
       const l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s };
       const u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5;
       return G7[u];
   }
  • The eT function generates a character based on the input position (e.x, e.y) and the current time (t.time).
  • It adjusts the position using some aspect ratio calculations and selects a character from G7 based on a combination of the position and time.
  • The purpose of YE function isn't directly clear from the code, but it seems to be a custom function used in this calculation.
  1. React Component (tT) for Displaying Dynamic Content:


```javascript
const tT = () => {
const e = j.useRef(null);
const [t, n] = j.useState({ height: null, width: null });
j.useEffect(() => {
function r() {
n({ height: window.innerHeight, width: window.innerWidth });
}
if (typeof window < "u") {
n({ height: window.innerHeight, width: window.innerWidth });
window.addEventListener("resize", r);
return () => window.removeEventListener("resize", r);
}
}, []);

   j.useEffect(() => {
       const r = e.current;
       if (!r) return;
       const i = 12;
       const s = ra(t.width / i) * 1.6;
       const o = ra(t.height / i);
       const l = { aspect: s / o };
       const u = setInterval(() => {
           let c = "";
           for (let d = 0; d < o; d++) {
               for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
               c += `

`;
}
r.textContent = c;
}, 1e3 / JE.fps);
return () => clearInterval(u);
}, [t]);

   return a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) });

};



   - This is a React component that sets up an interval to periodically update the content of a `div` element (`e.current`) with dynamically generated characters.
   - It calculates the number of columns (`s`) and rows (`o`) based on the window size and then fills the `div` with characters generated by the `eT` function.
   - The effect runs at a specified frames per second (`JE.fps`).

I followed up asking to "implement equivalent code in TypeScript and make it human readable" and got the following response:

import React, { useEffect, useRef, useState } from 'react';

const selectedCharacterSet =
  "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ";
const characterSetLength = selectedCharacterSet.length;

const calculateCharacter = (
  x: number,
  y: number,
  cols: number,
  rows: number,
  aspect: number,
  time: number,
): string => {
  const timeFactor = time * 0.000_08;
  const size = Math.min(cols, rows);
  const aspectRatio = aspect * 0.2;
  const position = {
    x: ((4 * (x - cols / 6.25)) / size) * aspectRatio,
    y: (5 * (y - rows / 4)) / size,
  };

  const index =
    Math.floor(
      Math.abs(
        Math.cos(position.x * position.x - position.y * position.y) -
          timeFactor,
      ) *
        characterSetLength +
        (Math.floor(x) % 2) * 2,
    ) % characterSetLength;
  return selectedCharacterSet[index];
};

type Size = {
  height: null | number;
  width: null | number;
};

const AsciiArtGenerator: React.FC = () => {
  const textRef = useRef<HTMLDivElement>(null);
  const [size, setSize] = useState<Size>({ height: null, width: null });

  useEffect(() => {
    const handleResize = () => {
      setSize({ height: window.innerHeight, width: window.innerWidth });
    };

    // Initial size setting
    handleResize();

    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  useEffect(() => {
    const element = textRef.current;
    if (!element || !size.width || !size.height) return undefined;

    const cols = Math.floor(size.width / 12) * 1.6;
    const rows = Math.floor(size.height / 12);
    const aspectRatio = cols / rows;

    const intervalId = setInterval(() => {
      let content = '';

      for (let y = 0; y < rows; y++) {
        for (let x = 0; x < cols; x++) {
          content += calculateCharacter(
            x,
            y,
            cols,
            rows,
            aspectRatio,
            Date.now(),
          );
        }

        content += '\n';
      }

      element.textContent = content;
    }, 1_000 / 60); // 60 fps

    return () => {
      clearInterval(intervalId);
    };
  }, [size]);

  return (
    <div
      ref={textRef}
      style={{
        height: '100%',
        overflow: 'hidden',
        whiteSpace: 'pre',
        width: '100%',
      }}
    />
  );
};

export default () => {
  return <AsciiArtGenerator />;
};
Enter fullscreen mode Exit fullscreen mode

To my surprise, the response is not only good enough, but it is also very readable.

Here is the above component in action.

Comparing the outputs, it looks like LLM response overlooked a few implementation details, but it is still a good enough implementation to learn from. Definitely a neat use case I've not considered before!

Top comments (6)

Collapse
 
punkpeye profile image
Frank Fiegel

Looks like dev.to editor does not support code blocks within block quotes. Sorry about the messy formatting.

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Looks like it does...

console.log('Code in block quote ')

Not sure what you did wrong?

Collapse
 
techman09 profile image
TechMan09

The tick marks need to be on their own line :)

Collapse
 
hosseinyazdi profile image
Hossein Yazdi

Yeah OpenAI and ChatGPT in general are good for pair programming, but I always use phind.com, since it's specifically configured for programming purposes and it's free as well!

Collapse
 
roshan_khan_28 profile image
roshan khan

it works for unminifying but sometime it hallucinates

Collapse
 
moopet profile image
Ben Sinclair

I think we just have to accept that everything from LLMs has a chance of being fiction.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.