Skip to content

Instantly share code, notes, and snippets.

@neverclear86
Created April 26, 2024 16:29
Show Gist options
  • Save neverclear86/6866dc20dd18a931c6bf2c72db4ba17c to your computer and use it in GitHub Desktop.
Save neverclear86/6866dc20dd18a931c6bf2c72db4ba17c to your computer and use it in GitHub Desktop.
うんこで考えるプログラミングパラダイムです。感想や変更提案も受け付けています。
// うんこ 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},
]
})
// うんこ 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.うんこ()
}
}
// うんこ 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