대수의 법칙

이론
대수의 법칙
동전 던지기
공개

2026-07-06

대수의 법칙을 이해하고 시각적으로 관찰할 수 있습니다. Shiny 앱으로 동전 던지기를 통한 대수의 법칙을 시각화하는 인터페이스를 제공하며, 사용자는 시행 횟수와 동전의 수를 조정하여 시뮬레이션을 시작할 수 있습니다. 또한, R 코드로 동전 던지기 시뮬레이션 함수를 정의하고 이를 통해 동전 던지기 결과의 누적 비율을 계산하여 그래프로 표현하는 예시가 제공됩니다.

#| label: shinylive-lln-coin
#| viewerHeight: 700
#| standalone: true

library(shiny)

library(bslib)
library(showtext)
tryCatch(sysfonts::font_add_google("Nanum Myeongjo", "kr"), error = function(e) NULL)
showtext_auto()

# ── Tufte 팔레트 · 테마 (자동 주입) ──────────────────────────
bit_cream <- "#fffff8"; bit_ink <- "#111111"; bit_rust <- "#8a1500"
bit_muted <- "#4a4a44"; bit_grid <- "#e8e6dc"; bit_axis <- "#8a8578"
theme_tufte_bit <- function(base_size = 13) {
  ggplot2::theme_minimal(base_size = base_size) +
    ggplot2::theme(
      text = ggplot2::element_text(family = "kr", colour = bit_ink),
      plot.title = ggplot2::element_text(family = "kr", size = base_size, hjust = 0),
      plot.background = ggplot2::element_rect(fill = bit_cream, colour = NA),
      panel.background = ggplot2::element_rect(fill = bit_cream, colour = NA),
      panel.grid.major = ggplot2::element_line(colour = bit_grid, linewidth = 0.3),
      panel.grid.minor = ggplot2::element_blank(),
      axis.line = ggplot2::element_line(colour = bit_axis, linewidth = 0.3),
      axis.ticks = ggplot2::element_line(colour = bit_axis, linewidth = 0.3)
    )
}
if (requireNamespace("ggplot2", quietly = TRUE)) ggplot2::theme_set(theme_tufte_bit())
bit_theme <- bs_theme(
  version = 5, bg = bit_cream, fg = bit_ink, primary = bit_rust,
  base_font = font_collection("Palatino Linotype", "Georgia", "Times New Roman", "serif"),
  "card-box-shadow" = "none"
)
# ─────────────────────────────────────────────────────────────

ui <- fluidPage(
  theme = bit_theme,
  titlePanel("대수의 법칙 — 동전 던지기"),

  sidebarLayout(
    sidebarPanel(
      sliderInput("n_trials", "시행 횟수:", min = 1, max = 1000, value = 100),
      sliderInput("n_coins", "동전 개수:", min = 1, max = 100, value = 1),
      actionButton("simulate", "동전 던지기 시작")
    ),

    mainPanel(
      plotOutput("coin_plot"),
      br(),
      p("이 앱은 동전 던지기 예제로 대수의 법칙을 보여줍니다."),
      p("동전을 반복해서 던질수록 시행 횟수가 늘어나면 앞면이 나올 확률은 0.5에 가까워집니다."),
      p("시행 횟수와 동전 개수를 조정하고 시뮬레이션을 시작해 보세요!")
    )
  )
)

server <- function(input, output) {

  coin_flips <- reactiveValues(data = NULL)

  observeEvent(input$simulate, {
    coin_flips$data <- replicate(input$n_coins, {
      cumsum(sample(c(0, 1), input$n_trials, replace = TRUE)) / (1:input$n_trials)
    })
  })

  output$coin_plot <- renderPlot({
    if (!is.null(coin_flips$data)) {
      matplot(coin_flips$data, type = "l", lty = 1, col = rainbow(input$n_coins),
              xlab = "시행 횟수", ylab = "앞면 비율", main = "동전 던지기 시뮬레이션",
              ylim = c(0, 1))
      abline(h = 0.5, lty = 2, col = "#4a4a44")
      legend("topright", legend = c("이론적 확률 (0.5)", paste0("동전 ", 1:input$n_coins)),
             lty = c(2, rep(1, input$n_coins)), col = c("#8a1500", rainbow(input$n_coins)))
    }
  })
}

shinyApp(ui, server)

라이센스