Skip to main content
Glama

OpenAI is shockingly good at unminifying code

Written by on .

engineering
openai

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

    Image

    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" } }) })
        );
    },

    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:

      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:

      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.

    3. React Component (

      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 />;
    };

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

    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!

    Update (2024-08-29): Initially, I thought that the LLM didn't replicate the logic accurately because the output was missing a few characters visible in the original component (e.g., ░▒▓█). However, a user on HN forum pointed out that it was likely a copy-paste error.

    Upon further investigation, I discovered that the original code contains different characters than what I pasted into ChatGPT. This appears to be an encoding issue, as I was able to get the correct characters after downloading the script. After updating the code to use the correct characters, the output is now identical to the original component.

    I apologize, GPT-4, for mistakenly accusing you of making mistakes.

    Written by punkpeye (@punkpeye)