Created
April 26, 2024 16:29
-
-
Save neverclear86/6866dc20dd18a931c6bf2c72db4ba17c to your computer and use it in GitHub Desktop.
うんこで考えるプログラミングパラダイムです。感想や変更提案も受け付けています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// うんこ with 関数型プログラミング | |
enum FoodStatus { | |
固形, | |
砕かれた, | |
粥状, | |
} | |
interface 栄養素 { | |
name: string | |
amount: number | |
} | |
type Food = { | |
name: string | |
status: FoodStatus | |
nutrition: 栄養素[] | |
} | |
const 吸収率 = 0.9 | |
const 噛み砕く = (food: Food): Food => { | |
if (food.status === FoodStatus.固形) { | |
return { | |
...food, | |
status: FoodStatus.砕かれた | |
} | |
} | |
return food | |
} | |
const 胃で消化 = (food: Food): Food => { | |
if (food.status === FoodStatus.砕かれた) { | |
return { | |
...food, | |
status: FoodStatus.粥状 | |
} | |
} | |
return food | |
} | |
const 小腸で吸収 = (food: Food): [Food, 栄養素[]] => { | |
if (food.status !== FoodStatus.粥状) return [food, []] | |
const to肝臓 = food.nutrition.map((nut) => ({...nut, amount: nut.amount * 吸収率})) | |
return [{ | |
...food, | |
nutrition: food.nutrition.map((nut) => ({...nut, amount: nut.amount * (1 - 吸収率)})) | |
}, to肝臓] | |
} | |
const 大腸で脱水 = (food: Food): Food => { | |
return {...food, status: FoodStatus.固形} | |
} | |
// 食べたものを元に新たなうんこの生成と、栄養を吸収した新たな肝臓を生成する関数を返す | |
const 消化プロセス = (food: Food) => { | |
const [ぐちゅぐちゅ, to肝臓] = 小腸で吸収(胃で消化(噛み砕く(food))) | |
const sendTo肝臓 = (肝臓: 栄養素[]) => { | |
const 新肝臓 = 肝臓.map((nut) => { | |
const existing = to肝臓.find((n) => n.name === nut.name) | |
if (existing) { | |
return {name: nut.name, amount: nut.amount + existing.amount} | |
} | |
return nut | |
}) | |
to肝臓.filter((nut) => !新肝臓.find((n) => n.name === nut.name)).forEach((nut) => 新肝臓.push(nut)) | |
return 新肝臓 | |
} | |
const うんこ = 大腸で脱水(ぐちゅぐちゅ) | |
return [うんこ, sendTo肝臓] | |
} | |
消化プロセス({ | |
name: 'おにぎり', | |
status: FoodStatus.固形, | |
nutrition: [ | |
{name: '炭水化物', amount: 50}, | |
{name: 'たんぱく質', amount: 10}, | |
{name: '脂質', amount: 5}, | |
] | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// うんこ with オブジェクト指向プログラミング | |
enum FoodStatus { | |
固形, | |
砕かれた, | |
粥状, | |
} | |
class 栄養素 { | |
private _name: string | |
private _amount: number | |
constructor(name: string, amount: number) { | |
this._name = name | |
this._amount = amount | |
} | |
get name(): string { | |
return this._name | |
} | |
get amount(): number { | |
return this._amount | |
} | |
} | |
class Food { | |
private _name: string | |
private _status: FoodStatus | |
private 栄養成分: 栄養素[] | |
constructor(name: string, nutrition: 栄養素[]) { | |
this._name = name | |
this._status = FoodStatus.固形 | |
this.栄養成分 = nutrition | |
} | |
get name(): string { | |
return this._name | |
} | |
get status(): FoodStatus { | |
return this._status | |
} | |
set status(status: FoodStatus) { | |
this._status = status | |
} | |
get 成分List(): string[] { | |
return this.栄養成分.map((n) => n.name) | |
} | |
getNutrition(name: string): number | undefined { | |
return this.栄養成分.find((n) => n.name === name)?.amount | |
} | |
gainNutrition(name: string, amount: number): void { | |
this.栄養成分.push(new 栄養素(name, amount)) | |
} | |
} | |
class 消化器官 { | |
private _肝臓: 栄養素[] = [] | |
readonly 消化率: number = 0.9 | |
private 消化中Food: Food | null = null | |
private うんこキュー: Food[] = [] | |
constructor() {} | |
private 噛み砕く(food: Food): void { | |
if (this.消化中Food != null) { | |
throw new Error('既に食べているものがあります') | |
} | |
this.消化中Food = food | |
this.消化中Food.status = FoodStatus.砕かれた | |
} | |
private 胃で消化(): void { | |
if (this.消化中Food == null) { | |
throw new Error('食べているものがありません') | |
} | |
this.消化中Food.status = FoodStatus.粥状 | |
} | |
private 小腸で吸収(): void { | |
if (this.消化中Food == null) { | |
throw new Error('食べているものがありません') | |
} | |
for (const nutrition of this.消化中Food.成分List) { | |
const amount = this.消化中Food.getNutrition(nutrition) | |
if (amount == null) { | |
continue | |
} | |
this._肝臓.push(new 栄養素(nutrition, amount * this.消化率)) | |
this.消化中Food.gainNutrition(nutrition, -amount * this.消化率) | |
} | |
} | |
private 大腸で脱水(): void { | |
if (this.消化中Food == null) { | |
throw new Error('食べているものがありません') | |
} | |
this.消化中Food.status = FoodStatus.固形 | |
this.うんこキュー.push(this.消化中Food) | |
this.消化中Food = null | |
} | |
食べる(food: Food): void { | |
this.噛み砕く(food) | |
this.胃で消化() | |
this.小腸で吸収() | |
this.大腸で脱水() | |
} | |
うんこ(): Food | null { | |
if (this.うんこキュー.length === 0) { | |
throw new Error('便意がありません') | |
} | |
return this.うんこキュー.shift() || null | |
} | |
} | |
// 新しい消化器官を生成しごはんを消化させる | |
function 食事() { | |
const digestProcess = new 消化器官() | |
const ごはん = new Food('ごはん', [new 栄養素('炭水化物', 100)]) | |
digestProcess.食べる(ごはん) | |
let うんこ = digestProcess.うんこ() | |
while (うんこ != null) { | |
うんこ = digestProcess.うんこ() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// うんこ with 構造化プログラミング | |
enum FoodStatus { | |
固形, | |
砕かれた, | |
粥状, | |
} | |
interface 栄養素 { | |
name: string | |
amount: number | |
} | |
type Food = { | |
name: string | |
status: FoodStatus | |
nutrition: 栄養素[] | |
} | |
const 吸収率 = 0.9 | |
const 便意しきい値 = 4 | |
let 肝臓: 栄養素[] = [] | |
let うんこタンク: Food[] = [] | |
function 噛み砕く(food: Food) { | |
if (food.status === FoodStatus.固形) { | |
food.status = FoodStatus.砕かれた | |
} | |
} | |
function 胃で消化する(food: Food) { | |
if (food.status === FoodStatus.砕かれた) { | |
food.status = FoodStatus.粥状 | |
} | |
} | |
function 小腸で吸収する(food: Food) { | |
if (food.status === FoodStatus.粥状) { | |
// 栄養素を吸収する | |
for (const nutrient of food.nutrition) { | |
肝臓[nutrient.name] += nutrient.amount * 吸収率 | |
nutrient.amount *= 1 - 吸収率 | |
} | |
} | |
} | |
function 大腸で排泄する(food: Food) { | |
if (food.status === FoodStatus.粥状) { | |
food.status = FoodStatus.固形 | |
} | |
} | |
function うんこする() { | |
const うんこs = [...うんこタンク] | |
うんこタンク = [] | |
let result = 0 | |
for (const うんこ of うんこs) { | |
if (うんこ.status !== FoodStatus.固形) { | |
result += 1 | |
} | |
} | |
return result | |
} | |
// 与えられた食べ物を消化し、終了うんコードを返す | |
function 消化プロセス(food: Food) { | |
噛み砕く(food) | |
胃で消化する(food) | |
小腸で吸収する(food) | |
大腸で排泄する(food) | |
うんこタンク.push(food) | |
if (うんこタンク.length >= 便意しきい値) { | |
return うんこする() | |
} | |
return 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment