ู†ู‚ู„ ุงู„ุฐุฆุจ ูˆุงู„ู…ุงุนุฒ ูˆุงู„ู…ู„ููˆู ุนุจุฑ ุงู„ู†ู‡ุฑ ุฏูˆู† ุฃูŠ ุชุฃุซูŠุฑ ุนู„ู‰ ุงู„ุฅูƒุณูŠุฑ

ู„ู‚ุฏ ุฃุตุจุญ ุจุงู„ูุนู„ ุชู‚ู„ูŠุฏู‹ุง ุฌูŠุฏู‹ุง - ูƒู„ ุดูŠุก ู…ุซูŠุฑ ู„ู„ุงู‡ุชู…ุงู… ุธู‡ุฑ ุนู„ู‰ Haskell - ูŠุชูƒุฑุฑ ุนู„ู‰ ุงู„ุฅูƒุณูŠุฑ.



ุงู„ุนู„ุงู…ุฉ ุงู„ุฃูˆู„ู‰ ูƒุงู†ุช " ุญูˆุงู„ูŠ 20 ุณุทุฑุงู‹ ู„ุนุฏ ุงู„ูƒู„ู…ุงุช " ุŒ ูˆุงู„ุชูŠ ุธู‡ุฑุช ุนู„ู‰ ุดูƒู„ ุญุฑู " ู‡ุฒูŠู…ุฉ C ุจุนุดุฑูŠู† ุณุทุฑุงู‹ ู…ู† ู‡ุงุณูƒู„: ูƒุชุงุจุฉ ู…ุฑุญุงุถูƒ ุงู„ุฎุงุต " ู…ู†0xd34df00d - ุตุงุฏูุช ุงู„ูŠูˆู… ุนุจุงุฑุฉ " ู†ู‚ู„ ุงู„ุฐุฆุจ ูˆุงู„ู…ุงุนุฒ ูˆุงู„ู…ู„ููˆู ุนุจุฑ ุงู„ู†ู‡ุฑ ู…ุน ุงู„ุชุฃุซูŠุฑุงุช ููŠ ู‡ุงุณูƒู„ " ู…ู†ูŠูˆูƒุงุณูŠู…ูˆู ูˆุฃูŠุถุง ู„ุง ูŠู…ูƒู† ุฃู† ุชู‚ุงูˆู….



ู„ุฐุง ุŒ ู‚ุงุจู„: ุงู„ู‚ูˆุฉ ุงู„ุบุงุดู…ุฉ ุงู„ู…ุชูˆุงุฒูŠุฉ ุบูŠุฑ ุงู„ู…ุชุฒุงู…ู†ุฉ ุงู„ูƒุงู…ู„ุฉ ุงู„ุจุทูŠุฆุฉ ู…ู‚ุงุจู„ ุงู„ุชุฃุซูŠุฑุงุช ุงู„ุฌุจุฑูŠุฉ.






ุจูŠุงู† ุงู„ู…ุดูƒู„ุฉ (ุชู… ู†ุณุฎู‡ ุจุงู…ุชู†ุงู† ู…ู† ุงู„ู…ู„ุงุญุธุฉ ุงู„ุฃุตู„ูŠุฉ):



ูƒุงู† ุงู„ูู„ุงุญ ููŠ ูŠูˆู… ู…ู† ุงู„ุฃูŠุงู… ุจุญุงุฌุฉ ุฅู„ู‰ ู†ู‚ู„ ุฐุฆุจ ูˆู…ุงุนุฒ ูˆู…ู„ููˆู ุนุจุฑ ุงู„ู†ู‡ุฑ. ูŠู…ุชู„ูƒ ุงู„ูู„ุงุญ ู‚ุงุฑุจู‹ุง ุŒ ุฅู„ู‰ ุฌุงู†ุจ ุงู„ูู„ุงุญ ู†ูุณู‡ ุŒ ูŠู…ูƒู† ุฃู† ูŠุตู„ุญ ููŠู‡ ุดูŠุก ูˆุงุญุฏ ูู‚ุท - ุฅู…ุง ุฐุฆุจ ุฃูˆ ู…ุงุนุฒ ุฃูˆ ู…ู„ููˆู. ุฅุฐุง ุชุฑูƒ ุงู„ูู„ุงุญ ุงู„ุฐุฆุจ ูˆุงู„ู…ุงุนุฒ ุฏูˆู† ุฑู‚ุงุจุฉ ุŒ ูŠุฃูƒู„ ุงู„ุฐุฆุจ ุงู„ู…ุงุนุฒ ุ› ุฅุฐุง ุชุฑูƒ ุงู„ูู„ุงุญ ุนู†ุฒุฉ ู…ุน ู…ู„ููˆู ุฏูˆู† ุฑู‚ุงุจุฉ ุŒ ูุฅู† ุงู„ู…ุงุนุฒ ุชุฃูƒู„ ุงู„ู…ู„ููˆู.

ุงู„ุฐุฆุจ โ†’ ุงู„ู…ุงุนุฒ โ†’ ุงู„ู…ู„ููˆู



: ยซ ยป, -, (+1 ). ,  โ€” , . , , . , ,  โ€”  .



, .



defmodule WolfGoatCabbage.State do
  @moduledoc """
     .

   (`true` โ†’ , ), `ltr` โ€”  ,  .
  """
  defstruct banks: %{true => [], false => []}, ltr: true, history: []
end

defmodule WolfGoatCabbage.Subj do
  @moduledoc """
   ,   .
  """
  defstruct [:me, :incompatible]
end


XIX , .



ุงู„ู‚ูŠู… ุงู„ุฃูˆู„ูŠุฉ



, .





@spec safe?(bank :: [%Subj{}]) :: boolean()
defp safe?(bank) do
  subjs =
    bank
    |> Enum.map(& &1.me)
    |> MapSet.new()
  incompatibles =
    bank
    |> Enum.flat_map(& &1.incompatible)
    |> MapSet.new()

  MapSet.disjoint?(subjs, incompatibles)
end


, , , , , . .



()



, , (nil ยซยป).



@spec move(%State{}, nil | %Subj{}) :: %State{} | false
@doc """
   ,  ,      
   ,     .
"""
defp move(%State{ltr: ltr, banks: banks, history: history} = state, nil) do
  with true <- not ltr, true <- safe?(banks[ltr]) do
    %State{state | ltr: not ltr, history: [length(history) | history]}
  end
end

@doc """
   , ,     โ€” 
  .

       , , 
  (      )  โ€”
      .     โ€”
  ,   โ€”  `false`.
"""
defp move(%State{banks: banks, ltr: ltr, history: history}, who) do
  with true <- who in banks[ltr],
        banks = %{ltr => banks[ltr] -- [who], not ltr => [who | banks[not ltr]]},
        bank_state = MapSet.new(banks[true]),
        true <- safe?(banks[ltr]),
        true <- not Enum.member?(history, bank_state) do
    %State{
      banks: banks,
      ltr: not ltr,
      history: [bank_state | history]
    }
  end
end


()



, , : . .



@initial %State{
            banks: %{true => @subjs, false => []},
            history: [MapSet.new(@subjs)]
         }

@spec go(%State{}) :: [MapSet.t()]
def go(state \\ @initial) do
  case state.banks[true] do
    [] -> # !
      Enum.reverse(state.history)

    _some ->
      [nil | @subjs]
      |> Task.async_stream(&move(state, &1))
      |> Stream.map(&elem(&1, 1)) # 
      |> Stream.filter(& &1)      # 
      |> Stream.flat_map(&go/1)   #   
  end
end


Stream, , , . , ?





: . main/0 .



ู‡ู†ุงูƒ ูุงุฑู‚ ุจุณูŠุท ูˆุงุญุฏ ู‡ู†ุง: ุณุชุนูˆุฏ ุงู„ุนุฏูŠุฏ ู…ู† ุงู„ุญู„ูˆู„ ูƒู‚ุงุฆู…ุฉ ุซุงุจุชุฉ ุจุณุจุจ Stream.flat_map/2. ู„ูƒู† ู‡ุฐุง ุฌูŠุฏ: ูŠู†ุชู‡ูŠ ูƒู„ ุญู„ ุจู…ุฌู…ูˆุนุฉ ูุงุฑุบุฉ ุŒ ู„ุฐู„ูƒ ูŠู…ูƒู†ู†ุง ุจุณู‡ูˆู„ุฉ ุชู‚ุณูŠู… ู‡ุฐู‡ ุงู„ูˆุฑู‚ุฉ ุงู„ู…ุณุทุญุฉ ุฅู„ู‰ ู‚ุทุน. ูƒู„ ูƒูˆุฏ ุงู„ุฅุฎุฑุงุฌ ุงู„ุฌู…ูŠู„ (ูˆุงู„ุฐูŠ ู‡ูˆ ุชู‚ุฑูŠุจู‹ุง ู…ุซู„ ุงู„ู…ู†ุทู‚) ู„ู† ุฃุนุทูŠู‡ุง ู‡ู†ุง ุŒ ู‡ู†ุง ุฌูˆู‡ุฑ ู„ู„ู…ุชุญู…ุณูŠู† .



ุงู„ุฐุฆุจ โ†’ ุงู„ู…ุงุนุฒ โ†’ ุงู„ู…ู„ููˆู






ู†ู‚ู„ ุฒุฑุงุนูŠ ุณุนูŠุฏ!




All Articles