Compare commits

..

2 Commits

Author SHA1 Message Date
09ee33a751
idklol 2023-09-24 08:21:22 -04:00
ee9fb1955c
Is it cat town? perhaps 2023-04-06 15:08:43 -04:00
168 changed files with 5087 additions and 4690 deletions

View File

@ -1,11 +0,0 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 90
[{*.c,*.go}]
indent_style = tab
indent_size = 4

3
cat-town/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/node_modules/
/src/*.js
/dist/

4838
cat-town/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
cat-town/package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "cat-town",
"version": "0.1.0",
"private": true,
"main": "index.js",
"scripts": {
"webpack": "webpack",
"dev": "webpack serve --config webpack.development.js",
"start": "npm run dev",
"build:dev": "webpack --config webpack.development.js",
"build:prod": "webpack --config webpack.production.js"
},
"devDependencies": {
"@excaliburjs/testing": "^0.25.1",
"clean-webpack-plugin": "^3.0.0",
"compression-webpack-plugin": "^7.1.2",
"html-webpack-plugin": "^5.5.0",
"source-map-loader": "^2.0.2",
"terser-webpack-plugin": "^5.3.6",
"ts-loader": "^9.4.2",
"typescript": "^4.9.4",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"excalibur": "^0.27.0"
}
}

View File

@ -0,0 +1,17 @@
import { Actor, Color, vec } from 'excalibur'
import { Resources } from '../resources'
export class Player extends Actor {
constructor() {
super({
pos: vec(150, 150),
width: 25,
height: 25,
color: new Color(255, 100, 100)
})
}
onInitialize() {
this.graphics.use(Resources.Cat.toSprite())
}
}

16
cat-town/src/cat.ts Normal file
View File

@ -0,0 +1,16 @@
// type Cat = {
// name string;
// years int;
// centimeters int;
// kilograms int;
// coloring Coloring;
// pattern Pattern;
// mood Mood;
// };
//
// type Coloring = 'orange' | 'black' | 'brown' | 'blue';
//
// type Pattern = 'plain' | 'striped' | 'spotted';
//
// type Mood = 'happy' | 'sad' | 'purring' |
// 'screaming' | 'mad' | 'scratchy' | 'curious' | 'concerned';

BIN
cat-town/src/images/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

30
cat-town/src/index.ts Normal file
View File

@ -0,0 +1,30 @@
import { Engine, Loader, DisplayMode } from 'excalibur'
import { Beginning } from './scenes/beginning'
import { Player } from './actors/player'
import { Resources } from './resources'
class Game extends Engine {
private player: Player
private beginning: Beginning
constructor() {
super({ displayMode: DisplayMode.FitScreen })
}
public start() {
this.beginning = new Beginning()
this.player = new Player()
this.beginning.add(this.player)
game.add('beginning', this.beginning)
const loader = new Loader(Object.values(Resources))
return super.start(loader)
}
}
const game = new Game()
game.start().then(() => {
game.goToScene('beginning')
})

View File

@ -0,0 +1,8 @@
import { ImageSource } from 'excalibur'
import catImage from './images/cat.png'
const Resources = {
Cat: new ImageSource(catImage)
}
export { Resources }

View File

@ -0,0 +1,7 @@
import { Engine, Scene } from 'excalibur'
export class Beginning extends Scene {
public onInitialize(engine: Engine) {}
public onActivate() {}
public onDeactivate() {}
}

22
cat-town/src/town.ts Normal file
View File

@ -0,0 +1,22 @@
// type Town = {
// grid Grid;
// };
//
// type Grid = {
// squares Map<Coords, Square>;
// };
//
// type Coords = {
// x int;
// y int;
// };
//
// type Square = {
// description string;
// things Map<string, Thing>;
// };
//
// type Thing = {
// name string;
// description string;
// };

14
cat-town/tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"sourceMap": true,
"target": "es2017",
"module": "es6",
"types": ["excalibur"],
"outDir": "./dist/",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}

View File

@ -0,0 +1,47 @@
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.ts",
target: "web",
output: {
filename: '[name].js',
sourceMapFilename: "[file].map",
path: path.resolve(__dirname, "dist"),
},
devtool: "source-map",
module: {
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource"
},
{
test: /\.js$/,
use: ["source-map-loader"],
exclude: [path.resolve(__dirname, "node_modules/excalibur")],
enforce: "pre",
},
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
optimization: {
splitChunks: {
chunks: "all",
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
title: "Cat Town",
}),
],
};

View File

@ -0,0 +1,12 @@
const { merge } = require("webpack-merge");
const common = require("./webpack.common");
module.exports = merge(common, {
mode: "development",
devtool: "inline-source-map",
devServer: {
static: {
directory: "./dist",
},
},
});

View File

@ -0,0 +1,13 @@
const { merge } = require("webpack-merge");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const common = require("./webpack.common");
module.exports = merge(common, {
mode: "production",
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
plugins: [new CompressionWebpackPlugin()],
});

View File

@ -1,19 +0,0 @@
#include <stdio.h>
/* print Fahrenheit-Celsius table
for f = 0, 20, ..., 300 */
int main() {
int lower, upper, step;
float fahr, celsius;
lower = 0; /* lower limit of temperature table */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%4.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}

View File

@ -1,12 +0,0 @@
#include <stdio.h>
#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */
int main() { /* Fahrenheit-Celsius table */
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
printf("%4d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

View File

@ -1,5 +0,0 @@
#include <stdio.h>
int main() {
printf("hello, world\n");
return 0;
}

2
djoy/.gitignore vendored
View File

@ -1,2 +0,0 @@
.venv/
*.sqlite3

View File

@ -1 +0,0 @@
3.12.6

View File

View File

@ -1,16 +0,0 @@
"""
ASGI config for djoy project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djoy.settings")
application = get_asgi_application()

View File

@ -1,125 +0,0 @@
"""
Django settings for djoy project.
Generated by 'django-admin startproject' using Django 5.1.1.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""
import os
import pathlib
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = pathlib.Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("DJOY_SECRET_KEY", "django-insecure-0xohno")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"polls.apps.PollsConfig",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "djoy.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "djoy.wsgi.application"
# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

View File

@ -1,24 +0,0 @@
"""
URL configuration for djoy project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("polls/", include("polls.urls")),
path("admin/", admin.site.urls),
]

View File

@ -1,16 +0,0 @@
"""
WSGI config for djoy project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djoy.settings")
application = get_wsgi_application()

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djoy.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()

View File

View File

@ -1,5 +0,0 @@
from django.contrib import admin
from .models import Question
admin.site.register(Question)

View File

@ -1,6 +0,0 @@
from django.apps import AppConfig
class PollsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "polls"

View File

@ -1,51 +0,0 @@
# Generated by Django 5.1.1 on 2024-09-16 01:23
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Question",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("question_text", models.CharField(max_length=200)),
("pub_date", models.DateTimeField(verbose_name="date published")),
],
),
migrations.CreateModel(
name="Choice",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("choice_text", models.CharField(max_length=200)),
("votes", models.IntegerField(default=0)),
(
"question",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="polls.question"
),
),
],
),
]

View File

@ -1,24 +0,0 @@
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,11 +0,0 @@
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("<int:question_id>/", views.detail, name="detail"),
path("<int:question_id>/results/", views.results, name="results"),
path("<int:question_id>/vote/", views.vote, name="vote"),
]

View File

@ -1,26 +0,0 @@
from django.http import HttpResponse
from .models import Question
def index(request) -> HttpResponse:
latest_question_list = Question.objects.order_by("-pub_date")[:5]
output = ", ".join([q.question_text for q in latest_question_list])
return HttpResponse(output.encode())
def detail(request, question_id) -> HttpResponse:
_ = request
return HttpResponse(f"You're looking at question {question_id}.".encode())
def results(request, question_id) -> HttpResponse:
_ = request
return HttpResponse(
f"You're looking at the results of question {question_id}".encode()
)
def vote(request, question_id) -> HttpResponse:
_ = request
return HttpResponse(f"You're voting on question {question_id}".encode())

View File

@ -1,3 +0,0 @@
Django
django-stubs
ruff

View File

@ -1,62 +0,0 @@
package main
import (
"fmt"
"os"
"strconv"
"strings"
)
func main() {
inBytes, err := os.ReadFile(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(1)
}
inLines := strings.Split(strings.TrimSpace(string(inBytes)), "\n")
inInts := make([]int64, len(inLines))
for i, line := range inLines {
v, err := strconv.ParseInt(line, 0, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(1)
}
inInts[i] = v
}
if err := insertionSort(inInts); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
os.Exit(1)
}
for _, i := range inInts {
fmt.Printf("%v\n", i)
}
}
func insertionSort(inInts []int64) error {
if len(inInts) < 2 {
return nil
}
for j := 1; j < len(inInts); j += 1 {
key := inInts[j]
fmt.Fprintf(os.Stderr, "%+v (save %v from %v)\n", inInts, key, j)
i := j - 1
for ; i > -1 && inInts[i] > key; i -= 1 {
inInts[i+1] = inInts[i]
fmt.Fprintf(os.Stderr, "%+v (j=%v i=%v)\n", inInts, j, i)
}
inInts[i+1] = key
fmt.Fprintf(os.Stderr, "%+v (insert %v at %v)\n", inInts, key, i+1)
}
return nil
}

View File

@ -1,38 +0,0 @@
import os
import sys
def main() -> int:
in_ints: list[int] = []
with open(sys.argv[1]) as infile:
for line in infile:
in_ints.append(int(line.strip()))
insertion_sort(in_ints)
for i in in_ints:
print(i)
return 0
def insertion_sort(in_ints: list[int]) -> None:
for i in range(len(in_ints) - 1):
j = i + 1
key = in_ints[j]
print(f"{in_ints} (save {key} from {j})", file=sys.stderr)
while i > -1 and in_ints[i] > key:
in_ints[i + 1] = in_ints[i]
print(f"{in_ints} (j={j} i={i})", file=sys.stderr)
i -= 1
in_ints[i + 1] = key
print(f"{in_ints} (insert {key} at {i+1})", file=sys.stderr)
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,10 +0,0 @@
11
2
17
-1
34
8
999
2
-56
3

View File

@ -1 +0,0 @@
export CFLAGS='-Werror -g'

View File

@ -1,3 +0,0 @@
carrot
angelfood
yellow

View File

@ -1,5 +0,0 @@
garble
geckle
gimple
gorble
gunkle

View File

@ -1,5 +0,0 @@
eggs
legs
pegs
jeggings
banana pants

View File

@ -1,2 +0,0 @@
ex17.db
l

View File

@ -1,2 +0,0 @@
ex17ec.db
l

View File

@ -1 +0,0 @@
ex17play.bin

View File

@ -1 +0,0 @@
set debuginfod enabled off

2
lcthw/.gitignore vendored
View File

@ -1,2 +0,0 @@
ex*
!ex*.c

View File

@ -1,35 +0,0 @@
SHELL := /bin/bash
CFLAGS ?= -Wall -g
GDBRUN = gdb --batch --ex run --ex bt --ex q --args
BUILD_TARGETS = $(foreach ex,$(wildcard ex*.c),$(subst .c,,$(ex)))
.PHONY: all
all: build test
.PHONY: echo
echo:
@echo BUILD_TARGETS=$(BUILD_TARGETS)
.PHONY: clean
clean:
rm -f $(BUILD_TARGETS)
.PHONY: build
build: $(BUILD_TARGETS)
.PHONY: gtest
gtest: $(BUILD_TARGETS)
@$(foreach bt, $(BUILD_TARGETS), make .gtest.$(bt) &&) printf '\ngYAY\n'
.gtest.%: %
@if test -f .$*.argv; then readarray -t test_argv <.$*.argv; fi && \
printf '\n==> %s\n' "$*" && $(GDBRUN) ./$* "$${test_argv[@]}"
.PHONY: test
test: $(BUILD_TARGETS)
@$(foreach bt, $(BUILD_TARGETS), make .test.$(bt) &&) printf '\nYAY\n'
.test.%: %
@if test -f .$*.argv; then readarray -t test_argv <.$*.argv; fi && \
printf '\n==> %s\n' "$*" && ./$* "$${test_argv[@]}"

View File

@ -1,12 +0,0 @@
#include <stdio.h>
/* This is a comment. */
int main(int argc, char *argv[])
{
int distance = 100;
// this is also a comment
printf("You are %d miles away.\n", distance);
return 0;
}

View File

@ -1,62 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("ERROR: You need at least one argument.\n");
// this is how you abort a program
return 1;
}
int i = 0;
int arg = 1;
for (arg = 1; arg < argc; arg++) {
for (i = 0; argv[arg][i] != '\0'; i++) {
printf("(%d) ", arg);
char letter = argv[arg][i];
// lowercase letters
if (letter >= 'A' && letter <= 'Z') {
letter += ('a' - 'A');
}
switch (letter) {
case 'a':
printf("%d: 'a'\n", i);
break;
case 'e':
printf("%d: 'e'\n", i);
break;
case 'i':
printf("%d: 'i'\n", i);
break;
case 'o':
printf("%d: 'o'\n", i);
break;
case 'u':
printf("%d: 'u'\n", i);
break;
case 'y':
// why i > 2? is this a bug?
if (i > 2) {
// it's only sometimes Y
printf("%d: 'y'\n", i);
} else {
printf("%d: %c is not a vowel\n", i, letter);
}
break;
default:
printf("%d: %c is not a vowel\n", i, letter);
}
}
}
return 0;
}

View File

@ -1,48 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
int numbers[4] = { 0 };
char name[4] = { 'a' };
// first, print them out raw
printf("numbers: %d %d %d %d\n",
numbers[0], numbers[1], numbers[2], numbers[3]);
printf("name each: %c %c %c %c\n",
name[0], name[1], name[2], name[3]);
printf("name: %s\n", name);
// setup the numbers
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
// setup the name
name[0] = 'Z';
name[1] = 'e';
name[2] = 'd';
name[3] = '\0';
// then print them out initialized
printf("numbers: %d %d %d %d\n",
numbers[0], numbers[1], numbers[2], numbers[3]);
printf("name each: %c %c %c %c\n",
name[0], name[1], name[2], name[3]);
// print the name like a string
printf("name: %s\n", name);
// another way to use name
char *another = "Zed";
printf("another: %s\n", another);
printf("another each: %c %c %c %c\n",
another[0], another[1], another[2], another[3]);
return 0;
}

View File

@ -1,32 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
int areas[] = { 10, 12, 13, 14, 20 };
char name[] = "Zed";
char full_name[] = {
'Z', 'e', 'd',
' ', 'A', '.', ' ',
'S', 'h', 'a', 'w', '\0',
};
// WARNING: On some systems you may have to change the
// %ld in this code to a %u since it will use unsigned ints
printf("The size of an int: %ld\n", sizeof(int));
printf("The size of areas (int[]): %ld\n", sizeof(areas));
printf("The number of ints in areas: %ld\n",
sizeof(areas) / sizeof(int));
printf("The first area is %d, the 2nd %d.\n", areas[0], areas[1]);
printf("The size of a char: %ld\n", sizeof(char));
printf("The size of name (char[]): %ld\n", sizeof(name));
printf("The number of chars: %ld\n", sizeof(name) / sizeof(char));
printf("The size of full_name (char[]): %ld\n", sizeof(full_name));
printf("The number of chars: %ld\n",
sizeof(full_name) / sizeof(char));
printf("name=\"%s\" and full_name=\"%s\"\n", name, full_name);
return 0;
}

View File

@ -1,26 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 0;
// go through each string in argv
// why am I skipping argv[0]?
for (i = 1; i < argc; i++) {
printf("arg %d: %s\n", i, argv[i]);
}
// let's make our own array of strings
char *states[] = {
"California",
"Oregon",
"Washington",
"Texas",
NULL,
};
for (i = 0; states[i] != NULL; i++) {
printf("state %d: %s\n", i, states[i]);
}
return 0;
}

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// forward declarations
void print_letters(size_t len, char arg[]);
void print_arguments(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < argc; i++) {
print_letters(strlen(argv[i]), argv[i]);
}
}
void print_letters(size_t len, char arg[])
{
int i = 0;
for (i = 0; i < len; i++) {
char ch = arg[i];
if (isprint((int)ch)) {
printf("'%c' == %d ", ch, ch);
}
}
printf("\n");
}
int main(int argc, char *argv[])
{
print_arguments(argc, argv);
return 0;
}

View File

@ -1,56 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
// create two arrays we care about
int ages[] = { 23, 43, 12, 89, 2 };
char *names[] = {
"Alan", "Frank",
"Mary", "John", "Lisa"
};
// safely get the size of ages
int count = sizeof(ages) / sizeof(int);
int i = 0;
char **first_name = &names[0];
char **last_name = &names[count - 1];
printf("first_name=%p last_name=%p\n", first_name, last_name);
printf("*first_name=%s *last_name=%s\n", *first_name, *last_name);
printf("---\n");
// first way using indexing
for (i = count - 1; i > -1; i--) {
printf("%s has %d years alive.\n", names[i], ages[i]);
}
printf("---\n");
// setup the pointers to the start of the arrays
int *cur_age = ages;
char **cur_name = names;
// second way using pointers
for (i = count - 1; i > -1; i--) {
printf("%s is %d years old.\n", *(cur_name + i), *(cur_age + i));
}
printf("---\n");
// third way, pointers are just arrays
for (i = count - 1; i > -1; i--) {
printf("%s is %d years old again.\n", cur_name[i], cur_age[i]);
}
printf("---\n");
// fourth way with pointers in a stupid complex way
for (cur_name = names, cur_age = ages;
(cur_age - ages) < count; cur_name++, cur_age++) {
printf("%s lived %d years so far.\n", *cur_name, *cur_age);
}
return 0;
}

View File

@ -1,73 +0,0 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
int height;
int weight;
};
struct Person *Person_create(char *name, int age, int height, int weight)
{
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->name = strdup(name);
who->age = age;
who->height = height;
who->weight = weight;
return who;
}
void Person_destroy(struct Person *who)
{
assert(who != NULL);
free(who->name);
free(who);
}
void Person_print(struct Person *who)
{
assert(who != NULL);
printf("Name: %s\n", who->name);
printf("\tAge: %d\n", who->age);
printf("\tHeight: %d\n", who->height);
printf("\tWeight: %d\n", who->weight);
}
int main(int argc, char *argv[])
{
// make two people structures
struct Person *joe = Person_create("Joe Alex", 32, 64, 100);
struct Person *frank = Person_create("Frank Blank", 20, 72, 180);
// print them out and where they are in memory
printf("Joe is at memory location %p:\n", joe);
Person_print(joe);
printf("Frank is at memory location %p:\n", frank);
Person_print(frank);
// make everyone age 20 years and print them again
joe->age += 20;
joe->height -= 2;
joe->weight += 40;
Person_print(joe);
frank->age += 20;
frank->weight += 20;
Person_print(frank);
// destroy them both so we clean up
Person_destroy(joe);
Person_destroy(frank);
return 0;
}

View File

@ -1,57 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
int height;
int weight;
};
struct Person Person_create(char *name, int age, int height, int weight)
{
struct Person who;
who.name = strdup(name);
who.age = age;
who.height = height;
who.weight = weight;
return who;
}
void Person_print(struct Person who)
{
printf("Name: %s\n", who.name);
printf("\tAge: %d\n", who.age);
printf("\tHeight: %d\n", who.height);
printf("\tWeight: %d\n", who.weight);
}
int main(int argc, char *argv[])
{
// make two people structures
struct Person joe = Person_create("Joe Alex", 32, 64, 100);
struct Person frank = Person_create("Frank Blank", 20, 72, 180);
// print them out and where they are in memory
printf("Joe is at memory location %p:\n", &joe);
Person_print(joe);
printf("Frank is at memory location %p:\n", &frank);
Person_print(frank);
// make everyone age 20 years and print them again
joe.age += 20;
joe.height -= 2;
joe.weight += 40;
Person_print(joe);
frank.age += 20;
frank.weight += 20;
Person_print(frank);
return 0;
}

View File

@ -1,237 +0,0 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define MAX_DATA 512
#define MAX_ROWS 100
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
struct Database {
struct Address rows[MAX_ROWS];
};
struct Connection {
FILE *file;
struct Database *db;
};
void die(const char *message)
{
if (errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
void Address_print(struct Address *addr)
{
printf("%d %s %s\n", addr->id, addr->name, addr->email);
}
void Database_load(struct Connection *conn)
{
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
if (rc != 1) {
die("Failed to load database.");
}
}
struct Connection *Database_open(const char *filename, char mode)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if (!conn) {
die("Memory error");
}
conn->db = malloc(sizeof(struct Database));
if (!conn->db) {
die("Memory error");
}
if (mode == 'c') {
conn->file = fopen(filename, "w");
} else {
conn->file = fopen(filename, "r+");
if (conn->file) {
Database_load(conn);
}
}
if (!conn->file) {
die("Failed to open file");
}
return conn;
}
void Database_close(struct Connection *conn)
{
if (conn) {
if (conn->file) {
fclose(conn->file);
}
if (conn->db) {
free(conn->db);
}
free(conn);
}
}
void Database_write(struct Connection *conn)
{
rewind(conn->file);
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
if (rc != 1) {
die("Failed to write database.");
}
rc = fflush(conn->file);
if (rc == -1) {
die("Cannot flush database");
}
}
void Database_create(struct Connection *conn)
{
int i = 0;
for (i = 0; i < MAX_ROWS; i++) {
struct Address addr = {.id = i, .set = 0};
conn->db->rows[i] = addr;
}
}
void Database_set(struct Connection *conn, int id, const char *name, const char *email)
{
struct Address *addr = &conn->db->rows[id];
if (addr->set) {
die("Already set, delete it first");
}
addr->set = 1;
char *res = strncpy(addr->name, name, MAX_DATA);
if (!res) {
die("Name copy failed");
}
addr->name[MAX_DATA - 1] = '\0';
res = strncpy(addr->email, email, MAX_DATA);
if (!res) {
die("Email copy failed");
}
addr->email[MAX_DATA - 1] = '\0';
}
void Database_get(struct Connection *conn, int id)
{
struct Address *addr = &conn->db->rows[id];
if (addr->set) {
Address_print(addr);
} else {
die("ID is not set");
}
}
void Database_delete(struct Connection *conn, int id)
{
struct Address addr = {.id = id, .set = 0};
conn->db->rows[id] = addr;
}
void Database_list(struct Connection *conn)
{
int i = 0;
struct Database *db = conn->db;
for (i = 0; i < MAX_ROWS; i++) {
struct Address *cur = &db->rows[i];
if (cur->set) {
Address_print(cur);
}
}
}
int main(int argc, char *argv[])
{
if (argc < 3) {
die("USAGE: ex17 <dbfile> <action> [action params]");
}
char *filename = argv[1];
char action = argv[2][0];
struct Connection *conn = Database_open(filename, action);
int id = 0;
if (argc > 3) {
id = atoi(argv[3]);
}
if (id >= MAX_ROWS) {
die("There's not that many records.");
}
switch (action) {
case 'c':
Database_create(conn);
Database_write(conn);
break;
case 'g':
if (argc != 4) {
die("Need an id to get");
}
Database_get(conn, id);
break;
case 's':
if (argc != 6) {
die("Need an id, name, email to set");
}
Database_set(conn, id, argv[4], argv[5]);
Database_write(conn);
break;
case 'd':
if (argc != 4) {
die("Need an id to delete");
}
Database_delete(conn, id);
Database_write(conn);
break;
case 'l':
Database_list(conn);
break;
default:
die("Invalid action: c=create, g=get, s=set, d=del, l=list");
}
Database_close(conn);
return 0;
}

View File

@ -1,305 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#define DEFAULT_MAX_DATA 512
#define DEFAULT_MAX_ROWS 100
struct Address {
char *name;
char *email;
};
struct TableOfContents {
size_t n_rows;
size_t string_field_size;
};
struct Database {
struct Address *rows;
};
struct Connection {
FILE *file;
struct TableOfContents *toc;
struct Database *db;
};
void Database_close(struct Connection *conn);
struct Address *Database_get(struct Connection *conn, const char *email);
void die(struct Connection *conn, const char *message)
{
Database_close(conn);
if (errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
void Address_print(struct Address *addr)
{
if (!addr) {
return;
}
printf("%s %s\n", addr->name, addr->email);
}
size_t Database_addr_size(struct Connection *conn)
{
return sizeof(struct Address) +
/* name */ conn->toc->string_field_size +
/* email */ conn->toc->string_field_size;
}
size_t Database_size(struct Connection *conn)
{
return sizeof(struct Database) +
(conn->toc->n_rows * Database_addr_size(conn));
}
size_t Database_n_rows(struct Connection *conn)
{
return sizeof(conn->db->rows) / Database_addr_size(conn);
}
void Database_load(struct Connection *conn)
{
int rc = 0;
rc = fread(conn->toc, sizeof(struct TableOfContents), 1, conn->file);
if (rc != 1) {
die(conn, "Failed to load TableOfContents.");
}
rc = fread(conn->db, Database_size(conn), 1, conn->file);
if (rc != 1) {
die(conn, "Failed to load Database.");
}
}
struct Connection *Database_open(const char *filename, char mode, size_t string_field_size)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if (!conn) {
die(conn, "Memory error allocating Connection");
}
conn->toc = malloc(sizeof(struct TableOfContents));
if (!conn->toc) {
die(conn, "Memory error allocating TableOfContents");
}
conn->toc->string_field_size = string_field_size;
conn->db = malloc(sizeof(struct Database));
if (!conn->db) {
die(conn, "Memory error allocating Database");
}
if (mode == 'c') {
conn->file = fopen(filename, "w");
conn->toc->n_rows = 1;
conn->db->rows = malloc(Database_addr_size(conn));
if (!conn->db->rows) {
die(conn, "Memory error allocating Database rows");
}
} else {
conn->file = fopen(filename, "r+");
if (conn->file) {
Database_load(conn);
}
}
if (!conn->file) {
die(conn, "Failed to open file");
}
return conn;
}
void Database_close(struct Connection *conn)
{
if (conn) {
if (conn->file) {
fclose(conn->file);
}
if (conn->toc) {
free(conn->toc);
}
if (conn->db) {
free(conn->db);
}
free(conn);
}
}
void Database_write(struct Connection *conn)
{
rewind(conn->file);
int rc = 0;
rc = fwrite(conn->toc, sizeof(struct TableOfContents), 1, conn->file);
if (rc != 1) {
die(conn, "Failed to write TableOfContents.");
}
rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
if (rc != 1) {
die(conn, "Failed to write Database.");
}
rc = fflush(conn->file);
if (rc == -1) {
die(conn, "Cannot flush");
}
}
void Database_set(struct Connection *conn, const char *name, const char *email)
{
struct Address *addr = Database_get(conn, email);
if (!addr) {
addr = malloc(Database_addr_size(conn));
conn->db->rows[Database_n_rows(conn)+1] = *addr;
}
char *res = strncpy(addr->name, name, conn->toc->string_field_size);
if (!res) {
die(conn, "Name copy failed");
}
addr->name[conn->toc->string_field_size - 1] = '\0';
res = strncpy(addr->email, email, conn->toc->string_field_size);
if (!res) {
die(conn, "Email copy failed");
}
addr->email[conn->toc->string_field_size - 1] = '\0';
}
struct Address *Database_get(struct Connection *conn, const char *email)
{
int i = 0;
struct Address *addr;
for (i = 0; i < Database_n_rows(conn); i++) {
addr = &conn->db->rows[i];
if (strcmp(addr->email, email) == 0) {
return addr;
}
}
return NULL;
}
void Database_delete(struct Connection *conn, const char *email)
{
struct Address *addr = Database_get(conn, email);
if (!addr) {
// already deleted
return;
}
addr->email = NULL;
addr->name = NULL;
}
void Database_list(struct Connection *conn)
{
int i = 0;
struct Database *db = conn->db;
for (i = 0; i < Database_n_rows(conn); i++) {
struct Address *cur = &db->rows[i];
Address_print(cur);
}
}
size_t get_string_field_size()
{
size_t string_field_size = DEFAULT_MAX_DATA;
const char *string_field_size_string = getenv("EX17_MAX_DATA");
if (string_field_size_string) {
int string_field_size_int = atoi(string_field_size_string);
string_field_size = string_field_size_int;
}
return string_field_size;
}
int main(int argc, char *argv[])
{
if (argc < 3) {
die(NULL, "USAGE: ex17 <dbfile> <action> [action params]");
}
char *filename = argv[1];
char action = argv[2][0];
size_t string_field_size = get_string_field_size();
struct Connection *conn = Database_open(filename, action, string_field_size);
switch (action) {
case 'c':
Database_write(conn);
break;
case 'g':
if (argc != 4) {
die(conn, "Need an `email` to get");
}
Address_print(Database_get(conn, argv[3]));
break;
case 's':
if (argc != 5) {
die(conn, "Need a `name` and `email` to set");
}
Database_set(conn, argv[3], argv[4]);
Database_write(conn);
break;
case 'd':
if (argc != 4) {
die(conn, "Need an `email` to delete");
}
Database_delete(conn, argv[3]);
Database_write(conn);
break;
case 'l':
Database_list(conn);
break;
default:
die(conn, "Invalid action: c=create, g=get, s=set, d=del, l=list");
}
Database_close(conn);
return 0;
}

View File

@ -1,109 +0,0 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAME_SIZE 64
struct State {
int counter;
time_t updated_at;
char name[NAME_SIZE];
size_t history_entries;
};
static char *names[] = {
"boingo",
"barko",
"flip",
"dingles",
"zebra",
"horus",
"blendy",
"kitems",
"horple",
NULL,
};
char *random_name()
{
int i = 0;
int mod = 0;
for (i = 0; names[i] != NULL; i++) {
mod = i;
}
return names[random() % mod];
}
void tick(FILE *fp, int init)
{
struct State *state = malloc(sizeof(struct State));
if (!state) {
err(EXIT_FAILURE, "Memory error making State");
}
if (init == 0) {
size_t read = fread(state, sizeof(struct State), 1, fp);
fprintf(
stderr,
"Read %d \"%s\" (%lu byte(s)) from %lu\n",
state->counter, state->name, sizeof(struct State) * read, state->updated_at
);
}
time_t history[state->history_entries];
size_t histories_read = fread(&history, sizeof(time_t), state->history_entries, fp);
state->counter++;
state->updated_at = time(0);
strncpy(state->name, random_name(), NAME_SIZE);
state->history_entries++;
rewind(fp);
size_t wrote = fwrite(state, sizeof(struct State), 1, fp);
fwrite(history, sizeof(time_t), sizeof(history) / sizeof(time_t), fp);
fwrite(&state->updated_at, sizeof(time_t), 1, fp);
fprintf(
stderr,
"Wrote %d \"%s\" (%lu byte(s)) at %lu (history length=%lu)\n",
state->counter, state->name, sizeof(struct State) * wrote, state->updated_at,
state->history_entries
);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
errx(EXIT_FAILURE, "Missing filename argument");
}
int random_seed = time(0);
const char *random_seed_str = getenv("RANDOM_SEED");
if (random_seed_str) {
random_seed = atoi(random_seed_str);
}
srandom(random_seed);
int init = 0;
FILE *fp = fopen(argv[1], "r+");
if (!fp) {
fp = fopen(argv[1], "w+");
init = 1;
}
if (!fp) {
err(EXIT_FAILURE, "Failed to open file");
}
tick(fp, init);
fclose(fp);
return 0;
}

View File

@ -1,12 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
int age = 10;
int height = 72;
printf("I am %d years old.\n", age);
printf("I am %d inches tall.\n", height);
return 0;
}

View File

@ -1,43 +0,0 @@
#include <stdio.h>
int main(int argc, char* argv[])
{
int distance = 100;
float power = 2.345f;
double super_power = 56789.4532;
char initial = 'A';
char first_name[] = "Zed";
char last_name[] = "Shaw";
printf("You are %d miles away.\n", distance);
printf("You have %f levels of power.\n", power);
printf("You have %f awesome super powers.\n", super_power);
printf("I have an initial %c.\n", initial);
printf("I have a first name %s.\n", first_name);
printf("I have a last name %s.\n", last_name);
printf("My whole name is %s %c. %s.\n",
first_name, initial, last_name);
int bugs = 100;
double bug_rate = 1.2;
printf("You have %d bugs at the imaginary rate of %f.\n",
bugs, bug_rate);
long universe_of_defects = 1L * 1024L * 1024L * 1024L;
printf("The entire universe has %ld bugs.\n", universe_of_defects);
double expected_bugs = bugs * bug_rate;
printf("You are expected to have %f bugs.\n", expected_bugs);
double part_of_universe = expected_bugs / universe_of_defects;
printf("That is only a %e portion of the universe.\n",
part_of_universe);
// this makes no sense, just a demo of something weird
char nul_byte = '\0';
int care_percentage = bugs * nul_byte;
printf("Which means you should care %d%%.\n", care_percentage);
return 0;
}

View File

@ -1,21 +0,0 @@
#include <stdio.h>
int main(int argc, char* argv[])
{
int i = 0;
if (argc == 1) {
printf("You have no argument.\n");
} else if (argc > 1 && argc < 4) {
printf("Here's your arguments:\n");
for (i = 0; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
} else {
printf("You have too many arguments.\n");
}
return 0;
}

View File

@ -1,15 +0,0 @@
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 25;
while (i > 0) {
printf("%d", i);
i--;
}
// need this to add a final newline
printf("\n");
return 0;
}

1
leetcode/.gitignore vendored
View File

@ -1 +0,0 @@
.envrc

View File

@ -1 +0,0 @@
3.12.0

File diff suppressed because one or more lines are too long

View File

@ -1,147 +0,0 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "leetcode"
description = 'What A Mess'
readme = "README.md"
version = "0.1.0"
requires-python = ">=3.7"
license = "MIT"
keywords = []
authors = [
{ name = "Dan Buch", email = "dan@meatballhat.com" },
]
classifiers = []
dependencies = [
"ipython",
"ipdb",
"matplotlib",
"numpy"
]
[tool.hatch.envs.default]
dependencies = [
"coverage[toml]>=6.5",
"pytest",
]
[tool.hatch.envs.default.scripts]
test = "pytest {args:tests}"
test-cov = "coverage run -m pytest {args:tests}"
cov-report = [
"- coverage combine",
"coverage report",
]
cov = [
"test-cov",
"cov-report",
]
[[tool.hatch.envs.all.matrix]]
python = ["3.7", "3.8", "3.9", "3.10", "3.11"]
[tool.hatch.envs.lint]
detached = true
dependencies = [
"black>=23.1.0",
"mypy>=1.0.0",
"ruff>=0.0.243",
]
[tool.hatch.envs.lint.scripts]
typing = "mypy --install-types --non-interactive {args:.}"
style = [
"ruff {args:.}",
"black --check --diff {args:.}",
]
fmt = [
"black {args:.}",
"ruff --fix {args:.}",
"style",
]
all = [
"style",
"typing",
]
[tool.black]
target-version = ["py37"]
line-length = 90
[tool.ruff]
target-version = "py37"
line-length = 90
select = [
"A",
"ARG",
"B",
"C",
"DTZ",
"E",
"EM",
"F",
"FBT",
"I",
"ICN",
"ISC",
"N",
"PLC",
"PLE",
"PLR",
"PLW",
"Q",
"RUF",
"S",
"T",
"TID",
"UP",
"W",
"YTT",
]
ignore = [
# Allow non-abstract empty methods in abstract base classes
"B027",
# Allow boolean positional values in function calls, like `dict.get(... True)`
"FBT003",
# Ignore checks for possible passwords
"S105", "S106", "S107",
# Ignore complexity
"C901", "PLR0911", "PLR0912", "PLR0913", "PLR0915",
# Allow print func
"T201",
# Allow assert statements
"S101",
]
unfixable = [
# Don't touch unused imports
"F401",
]
[tool.ruff.isort]
known-first-party = ["leetcode"]
[tool.ruff.flake8-tidy-imports]
ban-relative-imports = "all"
[tool.ruff.per-file-ignores]
# Tests can use magic values, assertions, and relative imports
"tests/**/*" = ["PLR2004", "S101", "TID252"]
[tool.coverage.run]
source_pkgs = ["leetcode", "tests"]
branch = true
parallel = true
omit = [
"src/leetcode/__about__.py",
]
[tool.coverage.paths]
leetcode = ["src/leetcode", "*/leetcode/src/leetcode"]
tests = ["tests", "*/leetcode/tests"]
[tool.coverage.report]
exclude_lines = [
"no cov",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
]

View File

@ -1,57 +0,0 @@
SIMPLE = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000,
}
SIMPLE_REVERSE = {v: k for k, v in SIMPLE.items()}
COMPOUND = {
"IV": 4,
"IX": 9,
"XL": 40,
"XC": 90,
"CD": 400,
"CM": 900,
}
PREFIXES = {k[0] for k in COMPOUND.keys()}
COMPOUND_REVERSE = {v: k for k, v in COMPOUND.items()}
ALL = SIMPLE | COMPOUND
ALL_REVERSE = {v: k for k, v in ALL.items()}
def i2r(i: int) -> str:
if i > 100_000:
raise ValueError(f"{i} is too silly")
r: list[str] = []
for int_val, roman_val in sorted(ALL_REVERSE.items(), reverse=True):
remainder = i % int_val
r += [roman_val] * int((i - remainder) / int_val)
i = remainder
return "".join(r)
def r2i(r: str) -> int:
total = 0
offset = 0
for i in range(len(r)):
if i + offset > len(r) - 1:
break
c = r[i + offset]
if c in PREFIXES and (i + offset + 1) < len(r) and c + r[i + offset + 1] in ALL:
total += ALL[c + r[i + offset + 1]]
offset += 1
continue
total += ALL[c]
return total

View File

@ -1,57 +0,0 @@
import itertools
import typing
def matrix_spiral(matrix: list[list[typing.Any]]) -> list[typing.Any]:
return [matrix[y][x] for x, y in matrix_spiral_path(matrix)]
def matrix_spiral_path(matrix: list[list[int]]) -> list[tuple[int, int]]:
snek = SpinSnek(matrix)
while snek.step():
...
return snek.path
COMPASS = (
(1, 0), # east
(0, 1), # south
(-1, 0), # west
(0, -1), # north
)
class SpinSnek:
def __init__(self, board: list[list[int]], loc: tuple[int, int] = (0, 0)):
self.max_loc: tuple[int, int] = (len(board[0]) - 1, len(board) - 1)
self.spinner: itertools.cycle[tuple[int, int]] = itertools.cycle(COMPASS)
self.direction = next(self.spinner)
self.path: list[tuple[int, int]] = [loc]
self.missteps: int = 0
def step(self) -> bool:
loc = self.path[-1]
next_loc: tuple[int, int] = (
loc[0] + self.direction[0],
loc[1] + self.direction[1],
)
if (
next_loc[0] > self.max_loc[0]
or next_loc[1] > self.max_loc[1]
or next_loc[0] < 0
or next_loc[1] < 0
or next_loc in self.path
):
self.direction = next(self.spinner)
if self.missteps > len(COMPASS) - 1:
return False
self.missteps += 1
return self.step()
self.missteps: int = 0
self.path.append(next_loc)
return True

View File

@ -1,169 +0,0 @@
import dataclasses
import typing
class LinkedListNode(typing.Protocol):
val: int
next: typing.Optional["LinkedListNode"]
class ListNode:
"""ListNode is the leetcode "standard library" type used in linked lists"""
def __init__(self, val: int = 0, next: typing.Optional["ListNode"] = None): # no qa
self.val = val
self.next = next
class ListNodeRandom:
"""ListNodeRandom is another weirdo linked list thing from
leetcode that is obviously very different than a binary tree
node :upside_down_face:
"""
def __init__(
self,
x: int,
next: typing.Optional["ListNodeRandom"] = None,
random: typing.Optional["ListNodeRandom"] = None,
):
self.val = x
self.next = next
self.random = random
@dataclasses.dataclass
class ListNodeRandomNicely:
val: int
next: typing.Optional["ListNodeRandomNicely"] = None
random: typing.Optional["ListNodeRandomNicely"] = None
class BinaryTreeNode(typing.Protocol):
val: int
left: typing.Optional["BinaryTreeNode"]
right: typing.Optional["BinaryTreeNode"]
class TreeNode:
"""TreeNode is the leetcode "standard library" type used in binary trees"""
def __init__(
self,
val: int = 0,
left: typing.Optional["TreeNode"] = None,
right: typing.Optional["TreeNode"] = None,
):
self.val = val
self.left = left
self.right = right
@classmethod
def from_int(cls, val: int | None) -> typing.Optional["TreeNode"]:
if val is None:
return None
return TreeNode(val)
# __repr__ was added by me
def __repr__(self) -> str:
filtered_parts = []
for key, value in [
("val", self.val),
("left", self.left),
("right", self.right),
]:
if value is not None:
filtered_parts.append((key, value))
middle = ", ".join([f"{k}={v!r}" for k, v in filtered_parts])
return f"TreeNode({middle})"
# __eq__ was added by me
def __eq__(self, other: typing.Optional["TreeNode"]) -> bool:
return (
other is not None
and self.val == other.val
and self.left == other.left
and self.right == other.right
)
class ConnectableBinaryTreeNode(typing.Protocol):
val: int
left: typing.Optional["BinaryTreeNode"]
right: typing.Optional["BinaryTreeNode"]
next: typing.Optional["BinaryTreeNode"]
class Node:
"""Node is the *other* leetcode "standard library" type used in binary trees"""
def __init__(
self,
val: int = 0,
left: typing.Optional["Node"] = None,
right: typing.Optional["Node"] = None,
next: typing.Optional["Node"] = None, # no qa
):
self.val = val
self.left = left
self.right = right
self.next = next
# __repr__ was added by me
def __repr__(self) -> str:
filtered_parts = []
for key, value in [
("val", self.val),
("right", self.right),
("left", self.left),
("next", self.next),
]:
if value is not None:
filtered_parts.append((key, value))
middle = ", ".join([f"{k}={v!r}" for k, v in filtered_parts])
return f"Node({middle})"
# __eq__ was added by me
def __eq__(self, other: "Node") -> bool:
return (
other is not None
and self.val == other.val
and self.left == other.left
and self.right == other.right
and self.next == other.next
)
# __list__ was added by me
def __list__(self) -> list[int | None]:
ret = [self.val]
ret += self.right.__list__() if self.right is not None else [None]
ret += self.left.__list__() if self.left is not None else [None]
ret += self.next.__list__() if self.next is not None else [None]
return ret
class NeighborlyNode:
"""NeighborlyNode is a "Node" type used in leetcode graph puzzles"""
def __init__(self, val=0, neighbors=None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
class NeighborlyNodeNicely(typing.NamedTuple):
val: int
neighbors: list["NeighborlyNodeNicely"]
def __eq__(self, other: typing.Optional["NeighborlyNodeNicely"]) -> bool:
return (
other is not None
and self.val == other.val
and [n.val for n in self.neighbors] == [n.val for n in other.neighbors]
)

View File

@ -1,640 +0,0 @@
import collections.abc
import copy
import random
import typing
import stdlib
def yep(s: str) -> bool:
return s.strip().lower().startswith("y")
def guess_bisect_repl(lower: int, upper: int) -> int:
mid = lower + ((upper - lower) // 2)
if yep(input(f"is it {mid}? ")):
return mid
if yep(input(f"higher than {mid}? ")):
return guess_bisect_repl(mid, upper)
return guess_bisect_repl(lower, mid)
def find_sqrt_ish(n: int) -> int:
return int(find_bisect(0, n, gen_sqrt_check(n)))
def gen_sqrt_check(n: int) -> typing.Callable[[float], int]:
def check(mid: float) -> int:
mid_sq: float = mid * mid
if mid_sq == n:
return 0
if mid_sq < n:
return 1
return -1
return check
def find_bisect(
lower: float, upper: float, check: typing.Callable[[float], int]
) -> float:
mid: float = lower + ((upper - lower) / 2)
print(f"lower={lower} mid={mid} upper={upper}")
if mid == lower or mid == upper or check(mid) == 0:
return mid
if check(mid) == 1:
return find_bisect(mid, upper, check)
return find_bisect(lower, mid, check)
def cartesian_path(p0: tuple[int, int], p1: tuple[int, int]) -> list[tuple[int, int]]:
path: list[tuple[int, int]] = []
if p0 < p1:
for i in range(p0[1], p1[1]):
path.append((i, p0[0]))
for i in range(p0[0], p1[0]):
path.append((p1[1], i))
else:
for i in range(p0[1], p1[1] - 1, -1):
path.append((i, p0[0]))
for i in range(p0[0] - 1, p1[0], -1):
path.append((p1[1], i))
return path
def gen_matrix(width: int, height: int) -> list[list[int]]:
return [list(range(width)) for _ in range(height)]
class MinStack:
def __init__(self):
self._v: list[int] = []
self._min: list[int] = []
def push(self, val: int) -> None:
self._v.append(val)
self._min.append(min(val, self._min[-1] if self._min else val))
def pop(self) -> None:
self._v.pop(-1)
self._min.pop(-1)
def top(self) -> int:
return self._v[-1]
def getMin(self) -> int: # no qa
return self._min[-1]
def linked_list_to_list(head: stdlib.LinkedListNode | None) -> list[int]:
seen: set[int] = set()
ret: list[int] = []
while head is not None:
if hash(head) in seen:
return ret
seen.add(hash(head))
ret.append(head.val)
head = head.next
return ret
def sort_linked_list(head: stdlib.LinkedListNode | None) -> stdlib.LinkedListNode | None:
by_val: list[tuple[int, stdlib.LinkedListNode]] = []
ret: stdlib.LinkedListNode | None = None
while head is not None:
by_val.append((head.val, head))
head = head.next
cur = ret
for _, node in sorted(by_val, key=lambda v: v[0]):
if cur is None:
cur = ret = node
continue
cur.next = node
cur = cur.next
if cur is not None:
cur.next = None
return ret
def connect_binary_tree_right(
root: stdlib.ConnectableBinaryTreeNode | None,
) -> tuple[stdlib.ConnectableBinaryTreeNode | None, list[int | None]]:
if root is None:
return None, []
by_level = binary_tree_by_level(copy.deepcopy(root))
by_level = typing.cast(dict[int, list[stdlib.ConnectableBinaryTreeNode]], by_level)
serialized: list[int | None] = []
print("")
if 0 not in by_level or len(by_level[0]) == 0:
return None, []
connected_root = by_level[0][0]
for level, nodes in sorted(by_level.items(), key=lambda p: p[0]):
for i in range(len(nodes)):
serialized.append(nodes[i].val)
if len(nodes) > i + 1:
print(f"{'-' * level}> connecting {nodes[i].val} -> {nodes[i + 1].val}")
nodes[i].next = nodes[i + 1]
serialized.append(None)
return connected_root, serialized
def binary_tree_by_level(
root: stdlib.BinaryTreeNode,
) -> dict[int, list[stdlib.BinaryTreeNode]]:
combined: dict[int, list[stdlib.BinaryTreeNode]] = {}
for path in collect_binary_tree_levels(0, root):
level, node = path
combined.setdefault(level, [])
combined[level].insert(0, node)
return combined
def collect_binary_tree_levels(
level: int, node: stdlib.BinaryTreeNode | None
) -> typing.Iterator[tuple[int, stdlib.BinaryTreeNode]]:
if node is None:
return
yield (level, node)
yield from collect_binary_tree_levels(level + 1, node.right)
yield from collect_binary_tree_levels(level + 1, node.left)
def sum_binary_tree_path_ints(root: stdlib.BinaryTreeNode | None) -> int:
path_ints: list[int] = []
for path in collect_binary_tree_paths(root):
path_ints.append(int("".join([str(node.val) for node in path])))
return sum(path_ints)
def binary_tree_paths_as_lists(
paths: list[list[stdlib.BinaryTreeNode]],
) -> list[list[int]]:
paths_vals: list[list[int]] = []
for path in paths:
paths_vals.append([node.val for node in path])
return paths_vals
def collect_binary_tree_paths(
node: stdlib.BinaryTreeNode | None,
) -> typing.Iterator[list[stdlib.BinaryTreeNode]]:
if node is None:
return
if node.right is None and node.left is None:
yield [node]
return
if node.right is not None:
for path in collect_binary_tree_paths(node.right):
yield [node] + path
if node.left is not None:
for path in collect_binary_tree_paths(node.left):
yield [node] + path
def binary_tree_from_list(inlist: list[int | None]) -> stdlib.BinaryTreeNode | None:
if len(inlist) == 0:
return None
nodes: list[stdlib.BinaryTreeNode | None] = [
typing.cast(stdlib.BinaryTreeNode | None, stdlib.TreeNode.from_int(i))
for i in inlist
]
nodes_copy = nodes[::-1]
root = nodes_copy.pop()
for node in nodes:
if node is None:
continue
if len(nodes_copy) == 0:
break
node.left = nodes_copy.pop()
if len(nodes_copy) > 0:
node.right = nodes_copy.pop()
return root
def binary_tree_from_preorder_inorder(
preorder: list[int], inorder: list[int]
) -> stdlib.BinaryTreeNode | None:
preorder_reversed = preorder[::-1]
def subtree(left: list[int], right: list[int]) -> stdlib.BinaryTreeNode:
root: stdlib.BinaryTreeNode = typing.cast(
stdlib.BinaryTreeNode, stdlib.TreeNode(preorder_reversed.pop())
)
if len(left) > 1:
split_pos = left.index(preorder_reversed[-1])
root.left = subtree(left[:split_pos], left[split_pos + 1 :])
elif len(left) == 1:
preorder_reversed.remove(left[0])
root.left = typing.cast(stdlib.BinaryTreeNode, stdlib.TreeNode(left[0]))
if len(right) > 1:
split_pos = right.index(preorder_reversed[-1])
root.right = subtree(right[:split_pos], right[split_pos + 1 :])
elif len(right) == 1:
preorder_reversed.remove(right[0])
root.right = typing.cast(stdlib.BinaryTreeNode, stdlib.TreeNode(right[0]))
return root
split_pos = inorder.index(preorder[0])
return subtree(inorder[:split_pos], inorder[split_pos + 1 :])
class JumpSpace(typing.NamedTuple):
pos: int
val: int
moves: list["JumpSpace"]
@classmethod
def from_board(
cls, pos: int = 0, board: typing.Iterable[int] = ()
) -> typing.Optional["JumpSpace"]:
board = list(board)
if len(board) == 0:
return None
space = cls(pos, board[pos], [])
space.collect(board)
return space
def collect(self, board: list[int]) -> None:
del self.moves[:]
if self.pos > len(board) or len(board) == 0:
return
for n in range(self.pos + 1, self.pos + self.val + 1):
if n >= len(board):
break
self.moves.append(typing.cast(JumpSpace, JumpSpace.from_board(n, board)))
def jump_paths(self) -> list[list[int]]:
ret: list[list[int]] = [[self.pos]]
for next_space in self.moves:
for path in next_space.jump_paths():
ret.append([self.pos] + path)
return ret
def collect_complete_jump_paths_from_board(board: list[int]) -> list[list[int]]:
return [
p
for p in collect_jump_paths_from_board(board)
if len(p) > 0 and p[-1] >= len(board) - 1
]
def collect_jump_paths_from_board(board: list[int]) -> list[list[int]]:
space = JumpSpace.from_board(0, board)
if space is None:
return []
return space.jump_paths()
# NOTE: the expensive way goes like this
# complete_paths = collect_complete_jump_paths_from_board(board)
# if len(complete_paths) == 0:
# return -1
# return min([len(p) - 1 for p in complete_paths])
def count_min_jumps_from_board(board: list[int]) -> int:
return len(collect_min_jumps_from_board(board))
def collect_min_jumps_from_board(board: list[int]) -> list[int]:
if len(board) < 3:
return list(range(1, len(board)))
jumps: list[int] = []
range_begin: int = 0
val = board[range_begin]
range_end: int = range_begin + val + 1
while range_end < len(board):
potential_jumps = board[range_begin:range_end]
scored_jumps = [
(val + range_begin + i, val, range_begin + i)
for i, val in enumerate(potential_jumps)
]
_, val, space = max(scored_jumps)
jumps.append(space)
range_begin = space
range_end = range_begin + val + 1
return jumps + [len(board) - 1]
def h_index(citations: list[int]) -> int:
last_qualified = None
for i, citation_count in enumerate(list(sorted(citations, reverse=True))):
if citation_count >= i + 1:
last_qualified = i + 1
else:
break
return last_qualified or 0
class SlowRandomizedSet:
def __init__(self):
self._i: set[int] = set()
def insert(self, val: int) -> bool:
ok = val not in self._i
self._i.add(val)
return ok
def remove(self, val: int) -> bool:
if val in self._i:
self._i.remove(val)
return True
return False
def getRandom(self) -> int:
return random.choice(list(self._i))
class RandomizedSet:
def __init__(self):
self._l: list[int] = []
self._m: dict[int, int] = {}
def insert(self, val: int) -> bool:
if val in self._m:
return False
self._m[val] = len(self._l)
self._l.append(val)
return True
def remove(self, val: int) -> bool:
if val not in self._m:
return False
val_loc = self._m[val]
last_val = self._l[-1]
self._l[val_loc] = last_val
self._m[last_val] = val_loc
self._l.pop()
self._m.pop(val)
return True
def getRandom(self) -> int:
return random.choice(self._l)
class TrieNode(typing.NamedTuple):
value: str
kids: dict[str, "TrieNode"]
@property
def is_leaf(self) -> bool:
return "__self__" in self.kids
@classmethod
def leaf(cls) -> "TrieNode":
return cls("__self__", {})
class Trie:
def __init__(self):
self._root_node = TrieNode("", {})
def insert(self, word: str) -> None:
if len(word) == 0:
return
current_node = self._root_node
for prefix in [word[: i + 1] for i in range(len(word))]:
current_node.kids.setdefault(prefix, TrieNode(prefix, {}))
current_node = current_node.kids[prefix]
leaf = TrieNode.leaf()
current_node.kids[leaf.value] = leaf
def search(self, word: str) -> bool:
return self._has(word, prefix_ok=False)
def startsWith(self, prefix: str) -> bool:
return self._has(prefix, prefix_ok=True)
def _has(self, word: str, prefix_ok: bool) -> bool:
if len(word) == 0:
return True
reverse_path = [word[: i + 1] for i in range(len(word))][::-1]
current_node = self._root_node
while reverse_path and current_node is not None:
current_node = current_node.kids.get(reverse_path.pop())
return (
current_node is not None
and (current_node.is_leaf or prefix_ok)
and current_node.value == word
)
def count_factorial_trailing_zeroes(number: int) -> int:
divisor: int = 5
zeroes_count: int = 0
while divisor <= number:
zeroes_count += number // divisor
divisor *= 5
return zeroes_count
def copy_random_list(
head: stdlib.ListNodeRandom | None,
) -> stdlib.ListNodeRandom | None:
if head is None:
return None
ordered = []
cur = head
while cur is not None:
ordered.append(cur)
cur = cur.next
ordered_copy = [stdlib.ListNodeRandom(entry.val) for entry in ordered]
hash_idx = {hash(n): i for i, n in enumerate(ordered)}
for i, entry in enumerate(ordered):
if i + 1 < len(ordered_copy):
ordered_copy[i].next = ordered_copy[i + 1]
if entry.random is not None:
ordered_copy[i].random = ordered_copy[hash_idx[hash(entry.random)]]
return ordered_copy[0]
def sum_max_sub_array(nums: list[int]) -> int:
mmax = last = prev = nums[0]
for i in range(1, len(nums)):
prev = nums[i] + last
last = max(nums[i], prev)
mmax = max(mmax, last)
return mmax
def sum_max_sub_array_i(nums: list[int]) -> tuple[int, int]:
mmax_i: int = 0
mmax = last = prev = nums[0]
for i in range(1, len(nums)):
prev = nums[i] + last
last = max(nums[i], prev)
mmax_i = i if last > mmax else mmax_i
mmax = max(mmax, last)
return mmax_i, mmax
def sum_max_sub_array_accum(nums: list[int]) -> int:
accum: list[int] = [nums[0]]
for i in range(1, len(nums)):
prev: int = nums[i] + accum[-1]
accum.append(max(nums[i], prev))
return max(accum)
def accum_sub_array_maxes(nums: list[int]) -> list[int]:
accum: list[int] = [nums[0]]
for i in range(1, len(nums)):
prev: int = nums[i] + accum[-1]
accum.append(max(nums[i], prev))
return accum
def neighborly_node_from_list(inlist: list[list[int]]):
# Alias "Node" type for leetcode compat
Node = stdlib.NeighborlyNodeNicely
if len(inlist) == 0:
return None
outlist = [Node(i + 1, []) for i in range(len(inlist))]
for i in range(len(inlist)):
outlist[i].neighbors[:] = []
for neighbor_val in inlist[i]:
outlist[i].neighbors.append(outlist[neighbor_val - 1])
return outlist[0]
def neighborly_node_to_list(node) -> list[list[int]]:
serialized: dict[int, list[int]] = {}
for cur in traverse_neighborly_node(node, serialized):
if cur is None:
break
serialized[cur.val] = [n.val for n in cur.neighbors]
return [v for _, v in sorted(serialized.items())]
def traverse_neighborly_node(
node: stdlib.NeighborlyNodeNicely, memo: collections.abc.Container[int]
) -> typing.Iterator[stdlib.NeighborlyNodeNicely | None]:
yield node
if node is None:
return
for neighbor in node.neighbors:
if neighbor.val in memo:
continue
yield from traverse_neighborly_node(neighbor, memo)
def find_min_in_rotated_array(nums: list[int]) -> int:
if nums[0] <= nums[-1]:
return nums[0]
if len(nums) <= 3:
return min(nums)
if nums[len(nums) // 2] > nums[-1]:
return find_min_in_rotated_array(nums[len(nums) // 2 :])
return find_min_in_rotated_array(nums[: (len(nums) // 2) + 1])

View File

@ -1,15 +0,0 @@
import pytest
import roman
@pytest.mark.parametrize(
("n", "expected"),
[
(3, "III"),
(58, "LVIII"),
(1994, "MCMXCIV"),
],
)
def test_int_to_roman(n: int, expected: str):
assert roman.i2r(n) == expected

View File

@ -1,46 +0,0 @@
import pytest
import spiral_matrix
@pytest.mark.parametrize(
("matrix", "expected"),
[
(
[
["a", "b", "c"],
["d", "e", "f"],
["g", "h", "i"],
],
["a", "b", "c", "f", "i", "h", "g", "d", "e"],
),
(
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
],
[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7],
),
(
[
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 5, 6, 7, 8, 9],
],
[] # noqa
+ [1, 2, 3, 4, 5, 6, 7, 8, 9] # right
+ [9, 9, 9] # down
+ [9, 8, 7, 6, 5, 4, 3, 2, 1] # left
+ [1, 1] # up
+ [1, 2, 3, 4, 5, 6, 7, 8] # right
+ [8] # down
+ [8, 7, 6, 5, 4, 3, 2] # left
+ [2, 3, 4, 5, 6, 7], # right
),
],
)
def test_matrix_spiral(matrix, expected):
assert spiral_matrix.matrix_spiral(matrix) == expected

View File

@ -1,505 +0,0 @@
import json
import pytest
import stuff
import stdlib
@pytest.mark.parametrize(
("n", "expected"),
[
(0, 0),
(1, 1),
(5, 2),
(4, 2),
(8, 2),
(9, 3),
],
)
def test_find_sqrt_ish(n: int, expected: int):
assert stuff.find_sqrt_ish(n) == expected
@pytest.mark.parametrize(
("ops", "expected"),
[
(
(
[
("new",),
("push", -2),
("push", 0),
("push", -3),
("getMin",),
("pop",),
("top",),
("getMin",),
]
),
[
None,
None,
None,
None,
-3,
None,
0,
-2,
],
)
],
)
def test_min_stack(ops: list[tuple[str] | tuple[str, int]], expected: list[int | None]):
returned: list[int | None] = []
inst: stuff.MinStack | None = None
for op in ops:
if len(op) == 1:
if op[0] == "new":
inst = stuff.MinStack()
returned.append(None)
continue
returned.append(getattr(inst, op[0])())
continue
method, arg = op
returned.append(getattr(inst, method)(arg))
assert returned == expected
@pytest.mark.parametrize(
("head", "expected"),
[
(None, None),
(
stdlib.ListNode(
4, stdlib.ListNode(2, stdlib.ListNode(1, stdlib.ListNode(3)))
),
stdlib.ListNode(
1, stdlib.ListNode(2, stdlib.ListNode(3, stdlib.ListNode(4)))
),
),
(
stdlib.ListNode(
4,
stdlib.ListNode(
19,
stdlib.ListNode(
14,
stdlib.ListNode(
5,
stdlib.ListNode(
-3,
stdlib.ListNode(
1,
stdlib.ListNode(
8,
stdlib.ListNode(
5, stdlib.ListNode(11, stdlib.ListNode(15))
),
),
),
),
),
),
),
),
stdlib.ListNode(
-3,
stdlib.ListNode(
1,
stdlib.ListNode(
4,
stdlib.ListNode(
5,
stdlib.ListNode(
5,
stdlib.ListNode(
8,
stdlib.ListNode(
11,
stdlib.ListNode(
14, stdlib.ListNode(15, stdlib.ListNode(19))
),
),
),
),
),
),
),
),
),
],
)
def test_sort_linked_list(
head: stdlib.LinkedListNode | None, expected: stdlib.LinkedListNode | None
):
if head is None:
assert stuff.sort_linked_list(head) == expected
return
assert stuff.linked_list_to_list(
stuff.sort_linked_list(head)
) == stuff.linked_list_to_list(expected)
@pytest.mark.parametrize(
("root", "expected"),
[
(
stdlib.Node(
1,
left=stdlib.Node(2, left=stdlib.Node(4), right=stdlib.Node(5)),
right=stdlib.Node(3, right=stdlib.Node(7)),
),
[1, None, 2, 3, None, 4, 5, 7, None],
),
],
)
def test_connect_binary_tree_right(
root: stdlib.ConnectableBinaryTreeNode | None, expected: list[int | None] | None
):
if expected is None:
assert root is None
return
connected, serialized = stuff.connect_binary_tree_right(root)
assert connected is not None
assert serialized == expected
@pytest.mark.parametrize(
("root", "expected"),
[
(
stdlib.Node(
4,
right=stdlib.Node(0),
left=stdlib.Node(9, right=stdlib.Node(1), left=stdlib.Node(5)),
),
1026,
),
],
)
def test_connect_binary_tree_sum_numbers(
root: stdlib.BinaryTreeNode | None, expected: int
):
assert stuff.sum_binary_tree_path_ints(root) == expected
@pytest.mark.parametrize(
("inlist", "expected"),
[
(
[3, 5, 1, 6, 2, 0, 8, None, None, 7, 4],
stdlib.TreeNode(
3,
left=stdlib.TreeNode(
5,
left=stdlib.TreeNode(6),
right=stdlib.TreeNode(
2,
left=stdlib.TreeNode(7),
right=stdlib.TreeNode(4),
),
),
right=stdlib.TreeNode(
1,
left=stdlib.TreeNode(0),
right=stdlib.TreeNode(8),
),
),
),
],
)
def test_binary_tree_from_list(
inlist: list[int | None], expected: stdlib.BinaryTreeNode | None
):
assert stuff.binary_tree_from_list(inlist) == expected
@pytest.mark.parametrize(
("preorder", "inorder", "expected"),
[
(
[3, 9, 20, 15, 7],
[9, 3, 15, 20, 7],
stdlib.TreeNode(
3,
left=stdlib.TreeNode(9),
right=stdlib.TreeNode(
20, left=stdlib.TreeNode(15), right=stdlib.TreeNode(7)
),
),
),
(
[-1],
[-1],
stdlib.TreeNode(-1),
),
(
[1, 2],
[1, 2],
stdlib.TreeNode(1, right=stdlib.TreeNode(2)),
),
],
)
def test_binary_tree_from_preorder_inorder(
preorder: list[int], inorder: list[int], expected: stdlib.BinaryTreeNode
):
assert stuff.binary_tree_from_preorder_inorder(preorder, inorder) == expected
@pytest.mark.parametrize(
("board", "expected"),
[
(
[2, 3, 1, 1, 4],
[
[0, 1, 2, 3, 4],
[0, 1, 3, 4],
[0, 1, 4],
[0, 2, 3, 4],
],
),
],
)
def test_collect_complete_jump_paths_from_board(
board: list[int], expected: list[list[int]]
):
assert list(sorted(stuff.collect_complete_jump_paths_from_board(board))) == expected
@pytest.mark.parametrize(
("board", "expected"),
[
(
[2, 3, 1, 1, 4],
2,
),
(
[2, 3, 0, 1, 4],
2,
),
(
[1],
0,
),
(
[1, 2],
1,
),
(
[6, 2, 6, 1, 7, 9, 3, 5, 3, 7, 2, 8, 9, 4, 7, 7, 2, 2, 8, 4, 6, 6, 1, 3],
4,
),
(
[3, 4, 3, 2, 5, 4, 3],
3,
),
(
[3, 2, 1],
1,
),
(
[1, 2, 3],
2,
),
],
)
def test_count_min_jumps_from_board(board: list[int], expected: int):
assert stuff.count_min_jumps_from_board(board) == expected
@pytest.mark.parametrize(
("citations", "expected"),
[
(
[3, 0, 6, 1, 5],
3,
),
(
[1, 3, 1],
1,
),
(
[100],
1,
),
],
)
def test_h_index(citations: list[int], expected: int):
assert stuff.h_index(citations) == expected
@pytest.mark.parametrize(
("cls",),
[
(stuff.SlowRandomizedSet,),
(stuff.RandomizedSet,),
],
)
def test_randomized_set(cls: type[stuff.RandomizedSet] | type[stuff.SlowRandomizedSet]):
inst = cls()
assert inst.insert(1) is True
assert inst.remove(2) is False
assert inst.insert(2) is True
assert inst.getRandom() in (1, 2)
assert inst.remove(1) is True
assert inst.insert(2) is False
assert inst.getRandom() == 2
inst = cls()
assert inst.insert(1) is True
assert inst.insert(10) is True
assert inst.insert(20) is True
assert inst.insert(30) is True
seen: set[int] = set()
for _ in range(10_000):
seen.add(inst.getRandom())
assert seen == {1, 10, 20, 30}
# ["remove","remove","insert","getRandom","remove","insert"]
# [[0],[0],[0],[],[0],[0]]
inst = cls()
assert inst.remove(0) is False
assert inst.remove(0) is False
assert inst.insert(0) is True
assert inst.getRandom() == 0
assert inst.remove(0) is True
assert inst.insert(0) is True
# ["RandomizedSet","insert","insert","remove","insert","remove","getRandom"]
# [[],[0],[1],[0],[2],[1],[]]
inst = cls()
assert inst.insert(0) is True
assert inst.insert(1) is True
assert inst.remove(0) is True
assert inst.insert(2) is True
assert inst.remove(1) is True
assert inst.getRandom() == 2
def test_trie_single_letter():
trie = stuff.Trie()
assert trie.insert("a") is None
assert trie.search("a") is True
assert trie.startsWith("a") is True
def test_trie_prefix_leaf():
trie = stuff.Trie()
assert trie.insert("apple") is None
assert trie.search("apple") is True
assert trie.search("app") is False
assert trie.startsWith("app") is True
assert trie.insert("app") is None
assert trie.search("app") is True
def test_trie_two_letter():
trie = stuff.Trie()
assert trie.insert("ab") is None
assert trie.search("a") is False
assert trie.startsWith("a") is True
def test_trie_busy():
trie = stuff.Trie()
assert trie.insert("app") is None
assert trie.insert("apple") is None
assert trie.insert("beer") is None
assert trie.insert("add") is None
assert trie.insert("jam") is None
assert trie.insert("rental") is None
assert trie.search("apps") is False
assert trie.search("app") is True
assert trie.search("ad") is False
assert trie.search("applepie") is False
assert trie.search("rest") is False
assert trie.search("jan") is False
assert trie.search("rent") is False
assert trie.search("beer") is True
assert trie.search("jam") is True
assert trie.startsWith("apps") is False
assert trie.startsWith("app") is True
assert trie.startsWith("ad") is True
assert trie.startsWith("applepie") is False
assert trie.startsWith("rest") is False
assert trie.startsWith("jan") is False
assert trie.startsWith("rent") is True
assert trie.startsWith("beer") is True
assert trie.startsWith("jam") is True
@pytest.mark.parametrize(
("nums", "expected"),
[
(
[-2, 1, -3, 4, -1, 2, 1, -5, 4],
6,
),
(
[1],
1,
),
(
[5, 4, -1, 7, 8],
23,
),
(
[-2, 1],
1,
),
(
json.load(open(".testdata/max_sub_array0.json")),
11081,
),
],
)
def test_max_sub_array(nums: list[int], expected: int):
assert stuff.sum_max_sub_array(nums) == expected
@pytest.mark.parametrize(
("inlist",),
[
([[2, 3, 4], [1, 7], [1], [1, 5, 6, 8], [4], [4], [2], [4]],),
([[2, 4], [1, 3], [2, 4], [1, 3]],),
],
)
def test_copy_neighborly_node(inlist):
orig = stuff.neighborly_node_from_list(inlist)
copied = stuff.neighborly_node_from_list(stuff.neighborly_node_to_list(orig))
assert id(orig) != id(copied)
assert orig == copied
assert stuff.neighborly_node_to_list(orig) == stuff.neighborly_node_to_list(copied)
@pytest.mark.parametrize(
("nums", "expected"),
[
([3, 4, 5, 1, 2], 1),
([4, 5, 6, 7, 0, 1, 2], 0),
([11, 13, 15, 17], 11),
],
)
def test_find_min_in_rotated_array(nums: list[int], expected: int):
assert stuff.find_min_in_rotated_array(nums) == expected

View File

@ -1 +0,0 @@
getting-started

View File

@ -1,23 +0,0 @@
/* This may look like nonsense, but really is -*- mode: C -*- */
/* The main thing that this program does. */
void main() {
// Decralations
int i;
double A[5] = {
9.0,
2.9,
3.E+25,
.00007,
};
// Doing some work
for (i = 0; i < 5; ++i) {
printf("element %d is %g, \tits square is %g\n",
i,
A[i],
A[i]*A[i]);
}
return 0;
}

View File

@ -1,24 +0,0 @@
/* This may look like nonsense, but really is -*- mode: C -*- */
#include <stdlib.h>
#include <stdio.h>
/* The main thing that this program does. */
int main(void) {
// Decralations
double A[5] = {
[0] = 9.0,
[1] = 2.9,
[4] = 3.E+25,
[3] = .00007,
};
// Doing some work
for (size_t i = 0; i < 5; ++i) {
printf("element %zu is %g, \tits square is %g\n",
i,
A[i],
A[i]*A[i]);
}
return EXIT_SUCCESS;
}

View File

@ -1,2 +0,0 @@
challenge-1
heron

View File

@ -1,90 +0,0 @@
#include <stdlib.h>
#include "array.h"
void IntArray_new(IntArray* a, size_t size) {
a->arr = malloc(size * sizeof(int));
a->used = 0;
a->size = size;
}
int IntArray_append(IntArray* a, int el) {
if (a->used == a->size) {
a->size *= 2;
a->arr = realloc(a->arr, a->size * sizeof(int));
}
a->used++;
a->arr[a->used] = el;
return a->used;
}
int IntArray_get(IntArray* a, int idx, int dflt) {
if (idx > a->used) {
return dflt;
}
return a->arr[idx];
}
int IntArray_length(IntArray* a) {
return a->used;
}
void IntArray_mergesort(IntArray* a) {
IntArray left_side;
IntArray right_side;
size_t split = a->used / 2;
IntArray_new(&left_side, split);
IntArray_new(&right_side, split);
for (int i = 0; i < split; ++i) {
IntArray_append(&left_side, IntArray_get(a, i, 0));
}
for (int i = split; i < a->used; ++i) {
IntArray_append(&right_side, IntArray_get(a, i, 0));
}
IntArray_mergesort(&left_side);
IntArray_mergesort(&right_side);
IntArray_mergesort_merge(a, &left_side, &right_side);
}
void IntArray_mergesort_merge(IntArray* a, IntArray* left_side, IntArray* right_side) {
IntArray_free(a);
size_t i = 0;
size_t j = 0;
while (i < left_side->used && j < right_side->used) {
if (left_side->arr[i] <= right_side->arr[j]) {
IntArray_append(a, left_side->arr[i]);
i++;
} else {
IntArray_append(a, right_side->arr[j]);
j++;
}
}
for (size_t li = 0; li < left_side->used; ++li) {
IntArray_append(a, left_side->arr[li]);
}
for (size_t ri = 0; ri < right_side->used; ++ri) {
IntArray_append(a, right_side->arr[ri]);
}
}
void IntArray_quicksort(IntArray* a) {
return;
}
void IntArray_free(IntArray* a) {
free(a->arr);
a->arr = NULL;
a->used = a->size = 0;
}

View File

@ -1,22 +0,0 @@
#ifndef INCLUDED_ARRAY_H
#include <stdlib.h>
typedef struct {
int *arr;
size_t used;
size_t size;
} IntArray;
void IntArray_new(IntArray*, size_t);
int IntArray_append(IntArray*, int);
int IntArray_get(IntArray*, int, int);
int IntArray_length(IntArray*);
void IntArray_mergesort(IntArray*);
void IntArray_mergesort_merge(IntArray*, IntArray*, IntArray*);
void IntArray_quicksort(IntArray*);
void IntArray_free(IntArray*);
#define INCLUDED_ARRAY_H 1
#endif

View File

@ -1,114 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include "array.h"
#define IODASH "-"
void usage(char* prog) {
fprintf(stderr, "Usage: %s [-f|--input-file <input-file>] [-o|--output-file <output-file>]\n", prog);
}
int main(int argc, char **argv) {
char* input_file = IODASH;
char* output_file = IODASH;
int c = 0;
while (1) {
static struct option long_options[] = {
{"input-file", required_argument, 0, 'f'},
{"output-file", required_argument, 0, 'o'},
};
int option_index = 0;
c = getopt_long(argc, argv, "f:o:", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 'f':
input_file = optarg;
break;
case 'o':
output_file = optarg;
break;
default:
usage(argv[0]);
return 1;
}
}
if (strcmp(input_file, IODASH) == 0) {
fprintf(stderr, "(reading from stdin)\n");
}
if (strcmp(output_file, IODASH) == 0) {
fprintf(stderr, "(writing to stdout)\n");
}
printf("input_file='%s' output_file='%s'\n", input_file, output_file);
FILE* instream;
instream = stdin;
if (strcmp(input_file, IODASH) != 0) {
instream = fopen(input_file, "r");
}
if (instream == NULL) {
perror("opening input file");
return EXIT_FAILURE;
}
FILE* outstream;
outstream = stdout;
if (strcmp(output_file, IODASH) != 0) {
outstream = fopen(output_file, "r");
}
if (outstream == NULL) {
perror("opening output file");
return EXIT_FAILURE;
}
int line_int;
ssize_t nread;
char* endptr = NULL;
char* line = NULL;
size_t len = 0;
IntArray accum;
IntArray_new(&accum, 100);
while ((nread = getline(&line, &len, instream)) != -1) {
IntArray_append(&accum, atoi(line));
}
printf("Accumulated %i ints\n", IntArray_length(&accum));
IntArray_mergesort(&accum);
printf("Merge sorted:\n");
for (int i = 0; i < accum.used; ++i) {
printf("%i: %i\n", i, IntArray_get(&accum, i, 0));
}
if (strcmp(input_file, IODASH) != 0) {
fclose(instream);
}
if (strcmp(output_file, IODASH) != 0) {
fclose(outstream);
}
return EXIT_SUCCESS;
}

View File

@ -1,40 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
/* lower and upper iteration limits centered around 1.0 */
static double const eps1m01 = 1.0 - 0x1P-01;
static double const eps1p01 = 1.0 + 0x1P-01;
static double const eps1m24 = 1.0 - 0x1P-24;
static double const eps1p24 = 1.0 + 0x1P-24;
int main(int argc, char* argv[argc+1]) {
for (int i = 1; i < argc; ++i) {
double const a = strtod(argv[i], 0);
double x = 1.0;
for (;;) {
double prod = a*x;
if (prod < eps1m01) {
x *= 2.0;
} else if (eps1p01 < prod) {
x *= 0.5;
} else {
break;
}
}
for (;;) {
double prod = a*x;
if ((prod < eps1m24) || (eps1p24 < prod)) {
x *= (2.0 - prod);
} else {
break;
}
}
printf("heron: a=%.5e,\tx=%.5e,\ta*x=%.12f\n",
a, x, a*x);
}
return EXIT_SUCCESS;
}

View File

@ -1 +0,0 @@
basic

View File

@ -1,9 +0,0 @@
#include <stdio.h>
int main() {
double x = 5.0;
double y = 3.0;
x = (x * 1.5) - y;
printf("x is \%g\n", x);
}

View File

@ -1 +0,0 @@
/vendor/

View File

@ -1,11 +0,0 @@
<?php
require_once 'vendor/autoload.php';
$hello_cmd = new Commando\Command();
$hello_cmd->option()->require()->describedAs('A person\'s name');
$name = $hello_cmd[0];
echo "Hello, $name", PHP_EOL;

View File

@ -1,14 +0,0 @@
{
"name": "meatballhat/personal-home-page",
"type": "library",
"require": {
"nategood/commando": "^0.4.0"
},
"license": "MIT",
"authors": [
{
"name": "Dan Buch",
"email": "dan@meatballhat.com"
}
]
}

View File

@ -1,124 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "4aa26239cdb17b13a548c56ac84b5749",
"packages": [
{
"name": "kevinlebrun/colors.php",
"version": "0.4.1",
"source": {
"type": "git",
"url": "https://github.com/kevinlebrun/colors.php.git",
"reference": "d132f36d06e48ea080855af19b4bcb1fb615224a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kevinlebrun/colors.php/zipball/d132f36d06e48ea080855af19b4bcb1fb615224a",
"reference": "d132f36d06e48ea080855af19b4bcb1fb615224a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"satooshi/php-coveralls": "dev-master",
"squizlabs/php_codesniffer": "1.*"
},
"type": "library",
"autoload": {
"psr-0": {
"Colors": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kevin Le Brun",
"email": "lebrun.k@gmail.com",
"homepage": "http://kevinlebrun.fr",
"role": "developer"
}
],
"description": "Colors for PHP CLI scripts",
"homepage": "https://github.com/kevinlebrun/colors.php",
"keywords": [
"cli",
"color",
"colors",
"console",
"shell"
],
"support": {
"issues": "https://github.com/kevinlebrun/colors.php/issues",
"source": "https://github.com/kevinlebrun/colors.php/tree/0.4.1"
},
"time": "2014-12-23T01:23:37+00:00"
},
{
"name": "nategood/commando",
"version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/nategood/commando.git",
"reference": "8fedd49fcb694faf60d87d5c2c4defdffa298fa0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nategood/commando/zipball/8fedd49fcb694faf60d87d5c2c4defdffa298fa0",
"reference": "8fedd49fcb694faf60d87d5c2c4defdffa298fa0",
"shasum": ""
},
"require": {
"kevinlebrun/colors.php": "~0.2",
"php": ">=5.6"
},
"type": "library",
"autoload": {
"psr-0": {
"Commando": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nate Good",
"email": "me@nategood.com"
}
],
"description": "PHP CLI Commando Style",
"homepage": "http://github.com/nategood/commando",
"keywords": [
"automation",
"cli",
"command",
"command line",
"command line interface",
"scripting"
],
"support": {
"issues": "https://github.com/nategood/commando/issues",
"source": "https://github.com/nategood/commando/tree/v0.4.0"
},
"time": "2019-07-10T02:37:11+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
<?php
echo "<h3>Hi, I'm a PHP script!</h3>";
?>
</body>
</html>

View File

@ -1,35 +0,0 @@
<?php
$name = 'Flavio';
var_dump($name);
$age = 20;
var_dump($age);
$base = 20;
$height = 10;
$area = $base * $height;
$test = 'an example';
$example = "This is $test";
print $example . "\n";
$firstName = 'Flavio';
$lastName = 'Copes';
$fullName = $firstName . ' ' . $lastName;
print '$fullName = ' . $fullName . "\n";
print strlen($fullName) . "\n";
$weirdName = str_replace('avio', 'ower', $fullName);
print '$weirdName = ' . $weirdName . "\n";
print 'exploded $weirdName = ' . var_dump(explode(' ', $weirdName)) . "\n";

View File

@ -1 +0,0 @@
<?php phpinfo(); ?>

View File

@ -1,6 +0,0 @@
<pre>
<?php
echo $_SERVER['HTTP_USER_AGENT'], PHP_EOL;
var_dump($_SERVER);
?>
</pre>

View File

@ -1,3 +1,11 @@
/out/
/*.d/out
/*.d/**/out
/custom_types/*
/hello/*
/primitives/*
/variable_bindings/*
/types/*
!/custom_types/*.rs
!/hello/*.rs
!/primitives/*.rs
!/variable_bindings/*.rs
!/types/*.rs

View File

@ -1,18 +0,0 @@
use std::convert::From;
#[allow(dead_code)]
#[derive(Debug)]
struct Number {
value: i32,
}
impl From<i32> for Number {
fn from(item: i32) -> Self {
Number { value: item }
}
}
fn main() {
let num = Number::from(30);
println!("My number is {:?}", num);
}

View File

@ -1,19 +0,0 @@
use std::convert::Into;
#[allow(dead_code)]
#[derive(Debug)]
struct Number {
value: i32,
}
impl Into<Number> for i32 {
fn into(self) -> Number {
Number { value: self }
}
}
fn main() {
let int = 5;
let num: Number = int.into();
println!("My number is {:?}", num);
}

View File

@ -1,16 +0,0 @@
use std::fmt;
struct Circle {
radius: i32,
}
impl fmt::Display for Circle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Circle of radius {}", self.radius)
}
}
fn main() {
let circle = Circle { radius: 6 };
println!("{}", circle.to_string());
}

View File

@ -1,7 +0,0 @@
fn main() {
let parsed: i32 = "5".parse().unwrap();
let turbo_parsed = "10".parse::<i32>().unwrap();
let sum = parsed + turbo_parsed;
println!("Sum: {:?}", sum);
}

Some files were not shown because too many files have changed in this diff Show More